Calculator

I would like to have two keys that can be activated at any time in the program. One to clear and reset and one to exit the program.

I also am having problems with my Error checking while loop. What am I doing wrong? It completely ignores alternative key strokes that should prompt a message that says invalid input. Instead the program does nothing. I am assuming it has to do with the semi-colon after the "error checking" while loop.
1
2
3
4
5
6
7
while (PlayAgain != 'y' && PlayAgain != 'Y' && PlayAgain != 'n' && PlayAgain != 'N'); // Semi-colon here
                                                        {
                                                                cin.clear();
                                                                cin.ignore(1000, '\n');
                                                                cout << "\nInvalid input. Would you like to use again? (y/n) ";
                                                                cin >> PlayAgain;
                                                        }


I am getting errors without the semi-colon and trying to move these loops around. Why is it telling me to put a semi-colon there? Wherecan I move this loop so it will function?
Here is the source:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
if (Game == 'b' || Game == 'B')  // Option B
    {
                cout << "\nBasic Calculator\n"  // Option Name
                        "\n";

                       do
                       {
                        cout << "Enter first number:            0 to exit\n> ";
                        cin >> cnum;    // Enter first number for calculation

                                while (cnum >= 'a' && cnum >= 'A' && cin.fail())    // Error checking for first number input
                                {
                                        cin.clear();
                                        cin.ignore(1000, '\n');
                                        cout << "\nInvalid input. Enter first number:\n" ;
                                        cin >> cnum;
                                }

                                if (cnum != 0)  // If first number doesn't equal close 0 continue
                                {
                                    cout << "\nEnter a operator (+ - / *) (C to clear)";

                                        do
                                        {
                                            cout << "\n> ";  // Enter operator
                                            cin >> symbol;

                                                while ( symbol != '+' && symbol != '-' && symbol != '/' && symbol != '*' && symbol != 'c' && symbol != 'C' && symbol != 0 && cin.fail())
                                                {
                                                    cin.clear();        //Error checking for operator input
                                                    cin.ignore(1000, '\n');
                                                    cout << "\nInvalid input. Enter a operator (+ - / *) (C to clear):\n" ;
                                                    cin >> symbol;
                                                }

                                                        if (symbol != 'c' && symbol != 'C' && symbol != 0)      // If operator doesn't equal clear (c) or close 0 continue
                                                        {
                                                            cout << "\nEnter second number (E to clear):\n>";
                                                            cin >> newNum;      // Enter second number for calculation

                                                                while ( newNum >= 'a' && newNum >= 'A' && cin.fail())
                                                                {
                                                                    cin.clear();            //Error checking second number input
                                                                    cin.ignore(1000, '\n');
                                                                    cout << "\nInvalid input. Enter second number (C to clear):\n" ;
                                                                    cin >> newNum;
                                                                }

                                                                    switch (symbol)
                                                                    {
                                                                            case '*':
                                                                            ansnum = cnum*newNum;      // Multiply input
                                                                            cout << "\n= " << ansnum;
                                                                            break;



                                                                            case '-':
                                                                            ansnum = cnum-newNum;       // Subtract unput
                                                                            cout << "\n= " << ansnum;
                                                                            break;


                                                                            case '+':
                                                                            ansnum = cnum+newNum;       // Add input
                                                                            cout << "\n= " << ansnum;
                                                                            break;



                                                                            case '/':
                                                                            ansnum = cnum / newNum;     // Divide input
                                                                            cout << "\n= " << ansnum;
                                                                            break;
                                                                    }
                                                }           cout << "\nWould you like to use again? (y/n)  ";
                                                            cin >> PlayAgain;                   //option to play again - loop
                                                            cout << "\n";

                                        }               while (PlayAgain != 'y' && PlayAgain != 'Y' && PlayAgain != 'n' && PlayAgain != 'N'); // Play again error check
                                                        {
                                                                cin.clear();
                                                                cin.ignore(1000, '\n');
                                                                cout << "\nInvalid input. Would you like to use again? (y/n) ";
                                                                cin >> PlayAgain;
                                                        }
                                }       while (PlayAgain == 'y' || PlayAgain == 'Y');  // Loop option A

                        }                      while (PlayAgain == 'y' || PlayAgain == 'Y');  // Loop option A
    }
Hi SGM3,

The first thing I notice is that there a lot of test like this repeated through the code.

while (PlayAgain != 'y' && PlayAgain != 'Y' && PlayAgain != 'n' && PlayAgain != 'N'); // Play again error check

and the code is nested to quite deep levels and more complicated than it should be. The nesting is not a problem in itself, I am saying that it might point to design that could be improved.

This tells me there is a problem with the design. Have a really good think about how to do this. A big clue is that all of your operators are binary ones (they take two arguments) Can you think of a better way of doing it? Here are some more clues: Use boolean values such as SeenFirstNum, SeenOperator, SeenSecondNum plus some others

Some other things:

You haven't specified types for all these variables - you are using the default type for whatever comes back from cin.

In this code:
1
2
3
4
case '/':
                                                                            ansnum = cnum / newNum;     // Divide input
                                                                            cout << "\n= " << ansnum;
                                                                            break;


ansnum is not declared anywhere and the expression does integer division. Is that what you want?

Also in this code:

1
2
3
4
5
6
7
8
9
10
11
12
cout << "Enter first number:            0 to exit\n> ";
                        cin >> cnum;    // Enter first number for calculation

                                while (cnum >= 'a' && cnum >= 'A' && cin.fail())    // Error checking for first number input
                                {
                                        cin.clear();
                                        cin.ignore(1000, '\n');
                                        cout << "\nInvalid input. Enter first number:\n" ;
                                        cin >> cnum;
                                }

                                if (cnum != 0)  // If first number doesn't equal close 0 continue 


You ask for input with 0 meaning exit and you don't test for 0 until you have done some other testing.

Here's another:

1
2
3
4
5
6
7
8
9
10
11
12
 do
                                        {
                                            cout << "\n> ";  // Enter operator
                                            cin >> symbol;

                                                while ( symbol != '+' && symbol != '-' && symbol != '/' && symbol != '*' && symbol != 'c' && symbol != 'C' && symbol != 0 && cin.fail())
                                                {
                                                    cin.clear();        //Error checking for operator input
                                                    cin.ignore(1000, '\n');
                                                    cout << "\nInvalid input. Enter a operator (+ - / *) (C to clear):\n" ;
                                                    cin >> symbol;
                                                }


There is only one variable in the while expression, so you can't use && operators (they would all have to be true for the code in braces to execute, which is impossible), so think about which operator would be better.

Any way I think I have given you quite a bit to think about.

TheIdeasMan
I forgot to mention the while loop at he start of your post.

Putting a semicolon after the while test expression means it's a null statement, so this becomes an infinite loop while the test expression is true.

Also as above, the && is not the right one to use.

If you have errors by removing the semicolon, then you have other problems.

Can you post your compiler output - I am intrigued as to what it says about this ( I think that you can redesign the whole thing better)


TheIdeasMan
I am new to C++. Over doing IF's and Loops practice. I have no knowledge of
booleans. I copied the calculator from a forum and am altering it.

This is part of a program with options. the first is a guessing game, second is the calculator, and the third...well have not decided yet.

I am just trying to understand the error checking (eg. when the user inputs a letter instead of a number) and the end loop to replay doesn't compile without the semi-colon but the semi-colon is making the loop a wall.
Yes. I have to edit the code (take out spaces for organization). Too long.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string> //Import for stings

using namespace std;

int main()
{
    srand(time(NULL));

    string name; // String for entered name
    char Menu = 'Y'; // Program menu
    char PlayAgain = 'Y'; // Program replay
    char Game;  // user inputs so far
    int cnum, newNum, ansnum; // Calc numbers
    char symbol;      // Calc oporators
    int num = 0;   // Guessing game number

            cout << "                                                                    Version 1.0\n";
            cout << "Hello, what is your name? ";
            cin >> name;                        // Intro statement.
            cin.ignore();
            cout << "\nHello, " << name <<"\n";

    do {
            cout << "\n\t\t\t_______________________________\n"
                    " \t\t\t| What would you like to use? |\n" // Options the program offers
                    " \t\t\t|-----------------------------|\n"
                    " \t\t\t|   (A) Guess the number      |\n"
                    " \t\t\t|   (B) Basic Calculator      |\n"
                    " \t\t\t|   (C) Print your text       |\n"
                    " \t\t\t|_____________________________|"
                    " \n";
            cin >> Game;            // Option chosen
            cin.ignore(1000, '\n');

        if  (Game == 'a' || Game == 'A') //Option A
        {
            do
            {
                    cout << "\nPick a number: (1-10)  ";
                    cin >> num;                         //users number choice
                    cin.ignore(1000, '\n');

                        while (num < 1 || num > 10 || cin.fail())  //error checking - number outside of range
                        {
                            cin.clear();                // clearing bad input, without enter "dslfkjn"
                            cin.ignore(1000, '\n');     // will cause program to go into a crazy loop

                            cout << "\nInvalid input. Pick a number (1-10)  ";
                            cin >> num;                 // re-enter a number within range
                            cin.ignore(1000, '\n');
                        }

                if (num == (rand() % 10 + 1))
                    //check users number with correct random number
                    cout << "\nCongradulations, you guessed correct. \n";
                   //if correct display this

                else
                    cout << "\nYou guessed wrong.\n";       //wrong choice display this

                        cout << "\nWould you like to play again? (y/n)  ";
                        cin >> PlayAgain;                   //option to play again - loop
                        cout << "\n";

                            while (PlayAgain != 'y' && PlayAgain != 'Y' && PlayAgain != 'n' && PlayAgain != 'N') // Play again error check
                            {
                                cin.clear();
                                cin.ignore(1000, '\n');
                                cout << "\nInvalid input. Would you like to play again? (y/n) ";
                                cin >> PlayAgain;
                            }
            }
                while (PlayAgain == 'y' || PlayAgain == 'Y');  // Loop option A
        }


    if (Game == 'b' || Game == 'B')  // Option B
    {
                cout << "\nBasic Calculator\n"  // Option Name
                        "\n";

                       do
                       {
                        cout << "Enter first number:            0 to exit\n> ";
                        cin >> cnum;    // Enter first number for calculation

         while (cnum >= 'a' && cnum >= 'A' && cin.fail())    // Error checking for first number input
    {
         cin.clear();
         cin.ignore(1000, '\n');
         cout << "\nInvalid input. Enter first number:\n" ;
         cin >> cnum;
     }

                                if (cnum != 0)  // If first number doesn't equal close 0 continue
                                {
                                    cout << "\nEnter a operator (+ - / *) (C to clear)";

                                        do
                                        {
                                            cout << "\n> ";  // Enter operator
                                            cin >> symbol;

                while ( symbol != '+' && symbol != '-' && symbol != '/' && symbol != '*' && symbol != 'c' && symbol != 'C' && symbol != 0 && cin.fail())
               {
               cin.clear();        //Error checking for operator input
               cin.ignore(1000, '\n');
               cout << "\nInvalid input. Enter a operator (+ - / *) (C to clear):\n" ;
               cin >> symbol;
         }

      if (symbol != 'c' && symbol != 'C' && symbol != 0)      // If operator doesn't equal clear (c) or close 0 continue
    {
      cout << "\nEnter second number (E to clear):\n>";
      cin >> newNum;      // Enter second number for calculation

           while ( newNum >= 'a' && newNum >= 'A' && cin.fail())
           {
                  cin.clear();            //Error checking second number input
                  cin.ignore(1000, '\n');
                  cout << "\nInvalid input. Enter second number (C to clear):\n" ;
                  cin >> newNum;
           }

                    switch (symbol)
                    {
                     case '*':
                     ansnum = cnum*newNum;      // Multiply input
                     cout << "\n= " << ansnum;
                     break;



                     case '-':
                     ansnum = cnum-newNum;       // Subtract unput
                     cout << "\n= " << ansnum;
                     break;


                    case '+':
                    ansnum = cnum+newNum;       // Add input
                    cout << "\n= " << ansnum;
                    break;



                    case '/':
                    ansnum = cnum / newNum;     // Divide input
                    cout << "\n= " << ansnum;
                    break;
                 }
                                                }           cout << "\nWould you like to use again? (y/n)  ";
                                                            cin >> PlayAgain;                   //option to play again - loop
                                                            cout << "\n";

                             }               while (PlayAgain != 'y' && PlayAgain != 'Y' && PlayAgain != 'n' && PlayAgain != 'N'); // Play again error check
                                          {
                                           cin.clear();
                                          cin.ignore(1000, '\n');
                                          cout << "\nInvalid input. Would you like to use again? (y/n) ";
                                           cin >> PlayAgain;
                                         }
                                }

         }                      while (PlayAgain == 'y' || PlayAgain == 'Y');  // Loop option A
    }
    if (Game == 'c' || Game == 'C')     // Option C
    {
        cout << "Enter a number ";
        cin.get();
    }

                    cout << "\nWould you like to return to the main menu? (y/n) ";  // Return to menu prompt
                    cin >> Menu;

                    while (Menu != 'y' && Menu != 'Y' && Menu != 'n' && Menu != 'N')    //Error checking for return menu input
                    {
                        cin.clear();
                        cin.ignore(1000, '\n');
                        cout << "\nInvalid input. Would You like to return to the main menu? (y/n) ";
                        cin >> Menu;
                    }
        }
                while (Menu == 'y' || Menu == 'Y');         // Program close prompt
                cout << "\nGoodbye,\n" << name << "\n";
                cin.ignore();
                return 0;
}
Be wary of coping code from forums - it may well have been written by some one with less experience than yourself!!! Or at least by someone with the wrong idea.

Did you understand what I meant by the && operator being the wrong one to use?

About compilation: Just because it compiles doesn't mean it's right. The semicolon needs to be removed. The problem is with the &&'s in the while test expression.

Anyway I think the whole thing should be redesigned. However send the compiler output, and I will explain what it is saying.

TheIdeasMan
I looked up th difference between && and ||. I didn't completely understand it. Do the && only apply to say:
while ( num == '1' && char == 'a' )


and || apply to:
while ( num == '1' || num == '2' )
&& means "and", and || means "or". The first statement in that post needs num to equal '1' and 'a', but your second only needs num to equal either '1' or '2' (or both also).

Things can get complicated:
1
2
3
4
char ch;
cin >> ch;
if ((ch >= 'A' && ch <= 'Z') || (ch >='a' && ch <= 'z'))
  cout << "you entered a letter";
Last edited on
No.

If you use && it means that all of the expresions have to evaluate to true for the whole test expression to be true, so that the statement following or the compound statement in braces will be executed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
unsigned short a =1;
unsigned short b =2;

if(a==1 && b == 2) { //both are true so do the code in the braces
      //some code
      
      }
else {  //one of them is false. It will never happen

};

if(a==1 && b == 3) { b==3 is false, so code in braces wont happen
     //this code is not executed
}
else {
     //this code is executed
}


Now the || operator means that if any one of the expressions is true then the test expression is true.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
unsigned short a =1;
unsigned short b =2;



if(a==1 || b == 3) { a==1 is true, so code in braces will happen
     //this code is executed
}
else {
     //this code is not executed
}
if(a==4 || b == 3) {both are false, so code in braces will not happen
     // this code is not executed
}
else {
     //this code is executed
};


You can have else if expression in if statements as well, but if there are lots of them you are better doing switch statements instead.

These test expressions work the same way for all of the loop statements ( for, while, do while). The case expressions in a switch statement are constant expressions not comparisons.

I would reccommend that get hold of "C Programming" by Kernigan & Ritchie. It is a small book, but really worthwhile. I know of some professional programmers who still look at it, after years of writing code.

I can see that you have re written some of your code, and I still think it needs a major re organisation. I don't like all the nested loops and repeated tests. I know that you have probably spent a lot oif time on it, but it really is a case of throwing good money after bad as it were.

Think about what I mentioned earlier:

Here are some more clues: Use boolean values such as SeenFirstNum, SeenOperator, SeenSecondNum plus some others


There are other types of calculators that do Reverse polish notation. This is not as hard as it sounds. Basically, instead of doing 1 + 2 =3 you do 1 2 + and the answer 3 is provided. This way, there is no need for parentheses, and it is easy to implement because all the operators take two arguments. Google.

TheIdeasMan

Thanks a lot. I have been at this for some time.

I don't know any other way of doing the "error" testing. I am a perfectionist. I don't like the user being able to type in anything when asked to type in a number without a response. Especially hate a never ending loop that floods the program.

I will pick up that book today. I am on summer break from college and have programming on my mind! I am determined! Walking out the door.

Thanks again!
If I remember rightly K&R has a RPN calculator example in it. It is about 20 lines I think ...
I am curious if reading a book on C is going to hurt me in C++. I have read people saying that learning C before C++ can cause problems because you have to unlearn habits from C that don't apply in C++
Well, your program is a C program really. The only C++ parts of are cout and cin.

C++ is much more complicated, and it has lots of stuff in it that means you can do things in very different ways. For example it has strings that you can concatenate using the + operator, whereas in C you have to call a function to do that. That was one tiny example, there are heaps and heaps of things that are done quite differently in C++.

It's true that lots of people write C++ code using classes, STL, templates etc, and then have a piece of code that uses a C approach.

However, it is also true that C++ is a superset of C, so there are a bunch things that are exactly the same. For example the things that form the heart of the language like control flow ( loops, if then else, switch),comparison expressions, basic data types (int float double etc), pointers (at least how they work and what you can do with them).

So I think it still worth learning the basics, and any C++ course still has to teach these.

I would reccommend getting K&R as well as a C++ book. Bjarne Strousop is the inventor of C++, apparently his book is really good, although I haven't read it.

Cheers TheIdeasMan
Topic archived. No new replies allowed.