Calculator

Started by
35 comments, last by Vinniee 17 years, 4 months ago
Ok guys, I have programmed this program so far but it does have some bugs.

#include <iostream>using namespace std;int main(){		char indicator = 'y';	while ( indicator == 'y' || indicator == 'Y' )	{		int value[2] = { 0, 0 };		char changeable[10] = { 0 };		int count = 0;		cin.getline( changeable, 10, ' ' );		if ( ( changeable[0] == 'a' ) & ( changeable[1] == 'd' ) * ( changeable[2] == 'd' ) )		{			cin>> value[0] >> value[1];			cout<< value[0] + value[1]				<< endl;		}		if ( ( changeable[0] == 'm' ) & ( changeable[1] == 'i' ) & ( changeable[2] == 'n' ) & ( changeable[3] == 'u' ) & ( changeable[4] == 's' ) )		{			cin>> value[0] >> value[1];			cout<< value[0] - value[1]				<< endl;		}		if ( ( changeable[0] == 's' ) & ( changeable[1] == 'u' ) & ( changeable[2] == 'b' ) & ( changeable[3] == 's' ) & ( changeable[4] == 't' ) & ( changeable[5] == 'r' ) & ( changeable[6] == 'a' ) & ( changeable[7] == 'c' ) & ( changeable[8] == 't' ) )		{			cin>> value[0] >> value[1];			cout<< value[0] / value[1]				<< endl;		}				if ( ( changeable[0] == 'm' ) & ( changeable[1] == 'u' ) & ( changeable[2] == 'l' ) & ( changeable[3] == 't' ) & ( changeable[4] == 'i' ) & ( changeable[5] == 'p' ) & ( changeable [6] == 'l' ) & ( changeable[7] == 'y' ) )		{			cin>> value[0] >> value[1];			cout<< value[0] * value[1]				<< endl;		}				cout<<"Do you want to do this again ( y or n )?: ";		cin>> indicator;	}	return 0;}


This is what goes wrong:

http://img166.imageshack.us/img166/4156/naamlooshy0.jpg

EDIT

Improved it a little bit:

#include <iostream>using std::cout;using std::cin;using std::endl;int main(){	int value[2] = { 0, 0 };	char x[10];	int array_number = 0;	int count = 0;	char indicator = 'y';	while ( indicator == 'y' || indicator == 'Y' )	{		cin.getline( x, 10, ' ' );		while ( x[count] != '\0' )			count++;		if ( count == 3 )		{			if ( ( x[0] == 'a' ) && ( x[1] == 'd' ) && ( x[2] == 'd' ) )			{				cin>> value[0] >> value[1];				cout<<"The result is: " << ( value[0] + value[1] )					<< endl;			}		}				if ( count == 8 )		{			if ( ( x[0] == 'm' ) && ( x[1] == 'u' ) && ( x[2] == 'l' ) && ( x[3] == 't' ) && ( x[4] == 'i' ) && ( x[5] == 'p' ) && ( x[6] == 'l' ) && ( x[7] == 'y' ) )			{				cin>> value[0] >> value[1];				cout<<"The result is: " << ( value[0] * value[1] )					<< endl;			}		}				if ( count == 6 )		{			if ( ( x[0] == 'd' ) && ( x[1] == 'i' ) && ( x[2] == 'v' ) && ( x[3] == 'i' ) && ( x[4] == 'd' ) && ( x[5] == 'e' ) )			{				cin>> value[0] >> value[1];				cout<<"The result is: " << ( value[0] / value[1] )					<< endl;			}		}		if ( count == 5 )		{			if ( ( x[0] == 'm' ) && ( x[1] == 'i' ) && ( x[2] == 'n' ) && ( x[3] == 'u' ) && ( x[4] == 's' ) )			{				cin>> value[0] >> value[1];				cout<<"The result is: " << ( value[0] - value[1] )					<< endl;			}		}		cout<<"Do you want to do this again?:";		cin>> indicator;	}	return 0;}


[Edited by - Vinniee on December 17, 2006 1:06:22 PM]
Advertisement
Vinnee, why are you examining your char arrays like that? That is absurd.

Use std::string. Like this:

#include <string>#include <iostream>void f(){    std::string s;    std::getline(cin,s);    if(s=="multiply")        {        // etc        }}


Please, please, please don't do:

if ( ( changeable[0] == 'm' ) & ( changeable[1] == 'u' ) & ( changeable[2] == 'l' ) & // etc


By the way, that won't work anyway because you are using & instead of &&. && is logical and in C++. A single & performs a binary AND on the bit patterns of the two arguments.
Quote:Original post by EasilyConfused
Vinnee, why are you examining your char arrays like that? That is absurd.

Use std::string. Like this:

#include <string>#include <iostream>void f(){    std::string s;    std::getline(cin,s);    if(s=="multiply")        {        // etc        }}


Please, please, please don't do:

if ( ( changeable[0] == 'm' ) & ( changeable[1] == 'u' ) & ( changeable[2] == 'l' ) & // etc


By the way, that won't work anyway because you are using & instead of &&. && is logical and in C++. A single & performs a binary AND on the bit patterns of the two arguments.


Hehe I just wanted to try :)
I'll rewrite my program with strings, thanks for the help :)

I'm still wondering the second code in that post doesn't work either ( yep, I replaced the & by &&'s ;) ).

Ok, done that but the same problem occurs with this code :)

#include <iostream>#include <string>using namespace std;int main(){		char indicator = 'y';	int value[2] = { 0, 0 };	string x;		while ( indicator == 'y' || indicator == 'Y' )	{		getline ( cin, x, ' ' );		if ( x == "multiply" )		{			cin>> value[0] >> value[1];			cout<<"The answer is: "				<< value[0] * value[1]				<< endl;		}		if ( x == "minus" )		{			cin>> value[0] >> value[1];			cout<<"The answer is: "				<< value[0] - value[1]				<< endl;		}		if ( x == "divide" )		{			cin>> value[0] >> value[1];			cout<<"The answer is: "				<< value[0] / value[1]				<< endl;		}		if ( x == "add" )		{			cin>> value[0] >> value[1];			cout<<"The answer is: "				<< value[0] + value[1]				<< endl;		}		cout<<"Do you want to do this again ( y or n )?: ";		cin>> indicator;	}	return 0;}


Checkout my screenshot in my post above, it's the same problem :)
It's probably the same problem as before when pulpfist was helping you out. After you cin >> to the second integer in each case, the trailing newline is left in the input stream.

You have two options - as before, you can call cin.ignore() after each time you do cin >> value[0] >> value[1] to remove the newline.

The other alternative is to read a whole line in (so omit the ' ' third param to getline) then put the result in an istringstream and parse the values out of the stringstream, as per the snippet I provided above.

[EDIT] If it helps, here is a complete example that takes a whole line of input at a time, then uses an istringstream to parse the input. As you can see, the stringstreams are as simple to use as cin really:

#include <iostream>#include <sstream>using namespace std;int main(){    string s,cont="y";    while(cont=="y" || cont=="Y")        {        getline(cin,s);        istringstream is(s);        string action;        int x,y;        is >> action;        if(action=="add")            {            is >> x >> y; cout << x+y << endl;            }        else if(action=="subtract")            {            is >> x >> y; cout << x-y << endl;            }        else if(action=="multiply")            {            is >> x >> y; cout << x*y << endl;            }        else if(action=="divide")            {            is >> x >> y;            if(y==0) cout << "Error: cannot divide by zero\n";            else cout << x/y << endl;            }        cout << "Do you want to go again?\n";        getline(cin,cont);        }    return 0;}


HTH Paul
Just some refactoring.

1) We *always* try to read two numbers for the mathematical operation, so let's extract the common code :)

2) It's often easier to make loops "clean" when you pull the condition into its own function - especially when there is I/O involved. This avoids special hacks with initializing values, finding that you need to scope a variable more widely than you thought, etc.

3) It seems nice to print an error message if the input was invalid :) (Note that by using this stringstream approach, you automatically "recover" from bad input; it can be quite tricky otherwise)

4) Plus my usual stylistic changes, stuff along the lines of "leave it out if you don't need it and it doesn't really clarify anything". (Except braces; I pretty much always put those.) Oh, and some reformatting; but really, that was fine before, I just have somewhat unusual taste for code indentation :)

#include <iostream>#include <sstream>using namespace std;bool prompt() {  string cont;  cout << "Do you want to go again?" << endl;  getline(cin, cont);  return cont == "Y" || cont == "y";}int main() {  do {    string s;    getline(cin, s);    istringstream is(s);    string action;    int x, y;        if (!(is >> action >> x >> y)) {      cout << "Error: bad input" << endl;      continue; // <-- a very useful keyword :)    }    if (action == "add") {      cout << x + y;    } else if (action == "subtract") {      cout << x - y;    } else if (action == "multiply") {      cout << x * y;    } else if (action == "divide") {      if (y == 0) { cout << "Error: cannot divide by zero"; }      else { cout << x / y; }    } else {      cout << "Error: no such operation: \"" << action << "\"";    }    cout << endl; // Another instance of something we can extract ;)  } while (prompt());}
if (!(is >> action >> x >> y)) {      cout << "Error: bad input" << endl;      continue; // <-- a very useful keyword :)

The !(....) operation is a NOT operation right? So if that operation is true, it is NOT true in the condition? :)

Thanks for the help m8's :D I'll first try if cin.ignore() works, and if it works.. I'll use the code posted above =D

Thanks for all the help guys!

This topic is closed to new replies.

Advertisement