Reputation: 27
okay. So I wrote a formula calculator a while ago that does many different functions. I opened it today and noticed that every time I accessed a certain function and then finished that function, the program went back to the main menu. Of course this is fine and I programmed it to do this, but I got annoyed when I accessed the calculator function (simple math) and I finished an equation, I couldn't do another right away. I want to be able to stay in a certain function until I press 'q', and then it will go back to the main menu.
The real problem, is that my function only accepts doubles, so if I put in a string ('q'), the program will just crash. I need a way to have the user enter either a string or a double so I can check if it's a 'q' and the user wants to quit.
I want to eventually do this with all of my functions, but here's just the "calc" function (the simplest one):
int calculation()
{
double x=0, y=0, answer=0;
char o;//operator variable
cout<<"calculation: ";
cin>>x>>o>>y; //I just don't know what to use here so that the user can enter a
cin.ignore(); //double or a string.
if (o=='+') answer=x+y;
else if (o=='-') answer=x-y;
else if (o=='*') answer=x*y;
else if (o=='/') answer=x/y;
else if (o=='^') answer= pow(x, y);
else if (o=='%') {
answer= (100/x)*y;
cout<<"answer= "<<answer<<"%";
}
if (o!='%') cout<<"answer= "<<answer;
cin.get();
return 0;
}
I need the function to keep repeating until the user enters a single "q". Sorry for all the words.
Upvotes: 0
Views: 1109
Reputation: 44468
Solve it in two steps:
After that, you can customize your functions however you want. One possibility would be mapping strings for operators to callbacks that take two operands and print a result. You would then pass that mapping in to your calculation function so that the number of operators you support can increase with ease.
Here's a very rough example that only works for addition, but demonstrates the concept.
#include <iostream>
#include <cmath>
#include <sstream>
#include <map>
using namespace std;
typedef double (*p_fn)(double,double);
double add(double x, double y)
{
return x + y;
}
typedef map<string,p_fn> operators;
double execute( const operators &op, double x, double y, const string& o )
{
operators::const_iterator i = op.find(o);
if( i != op.end())
{
p_fn f = i->second;
double const result = f(x,y);
return result;
}
cout<<"unknown operator\n";
return 0;
}
bool get_data( double& x, double&y, string& o )
{
string s1,s2,s3;
cin>>s1;
if(s1=="q")
return false;
cin>>s2>>s3;
stringstream sstr;
sstr<<s1<<" "<<s2<<" "<<s3;
sstr>>x>>o>>y;
stringstream sstr2;
sstr2<<x<<" "<<o<<" "<<y;
return sstr.str() == sstr2.str();
}
double calculation2( const operators& op )
{
double x,y;
string o;
while(get_data(x,y,o))
cout<<execute(op, x, y, o)<<"\n";
return 0;
}
int main(int argc, char* argv[])
{
operators o;
o["+"]=add;
calculation2(o);
return 0;
}
This example uses pointers to functions to map the string "+" to the function add(x,y). It also uses stringstreams to perform very basic input validation.
Upvotes: 2