Hello
I am new to C++ programming and i am trying to write a c++ class for a calculator. I am having trouble with my get_token function where i'm trying to read one character at a time and if the character represents a number , it should convert it into a double type.
This is possible when you are reading the expression to be evaluated is read through the keyboard by using the commands
char ch;
int n;
cin>>ch;
cin.pushback(ch);
cin>>n;
but now i'm trying to read out the expression from a string...i'm not sure which command to use
here is the code i'm using. Thank you :)
Calc.h
#ifndef CALC_H
#define CALC_H
#include <string>
#include <map>
#include <cctype>
enum Token_value
{
NAME, NUMBER, END,
PLUS='+', MINUS='-', MUL='*', DIV='/',
PRINT=';', ASSIGN='=', LP='(', RP=')'
};
class Calculator
{
public:
Calculator() {defined=false;cur_tok=PRINT;}
void Get(string str,istream &is);
void Show(ostream &os);
Token_value get_token(int &index);
double Prim(bool get,int &index);
double Term(bool get,int &index);
double Expr(bool get,int &index);
double Eval();
double error(const string& s);
private:
bool defined;
string expr;
Token_value cur_tok;
};
#endif
Calc.cpp
#include <iostream>
#include <string>
#include <map>
#include <cctype>
using namespace std;
#include "Calc.h"
double number_value;
string string_value;
int no_of_errors;
map<string,double> table;
double Calculator::Expr(bool get,int &index)
{
double left=Term(get,index);
for(;;)
switch(cur_tok)
{
case PLUS:
left+=Term(true,index);
break;
case MINUS:
left-=Term(true,index);
break;
default:
return left;
}
}
double Calculator::Term(bool get,int &index)
{
double left=Prim(get,index);
for(;;)
switch(cur_tok)
{
case MUL:
left*=Prim(true,index);
break;
case DIV:
if(double d=Prim(true,index))
{
left/=d;
break;
}
return error("divide by 0");
default:
return left;
}
}
double Calculator::Prim(bool get,int &index)
{
if(get)get_token(index);
switch (cur_tok)
{
case NUMBER:
{
double v=number_value;
get_token(index);
return v;
}
case NAME:
{
//Name *n3=t1.lookup(string_value);
double &v=table[string_value];
if(get_token(index)==ASSIGN) v=Expr(true,index);
return v;
}
case MINUS:
return -Prim(true,index);
case LP:
{
double e=Expr(true,index);
if(cur_tok!=RP) return error(") expected");
get_token(index);
return e;
}
default:
return error("primary expected");
}
}
Token_value Calculator::get_token(int &index)
{
char ch=expr[index];
cout<<"data="<<expr[index]<<'\n';
int n;
n=atoi(&ch);
cout<<"n="<<n<<'\n';
index++;
switch(ch)
{
case 0:
return cur_tok=END;
case ';':
case '*':
case '/':
case '+':
case '-':
case '(':
case ')':
case '=':
return cur_tok=Token_value(ch);
case '0':case '1':case '2':case '3':case '4':
case '5':case '6':case '7':case '8':case '9':
case '.':
cin.putback(ch);
cin>>number_value;
return cur_tok=NUMBER;
default:
if(isalpha(ch))
{
cin.putback(ch);
cin>>string_value;
return cur_tok=NAME;
}
error("bad token");
return cur_tok=PRINT;
}
}
double Calculator::error(const string& s)
{
no_of_errors++;
cerr<<"error:"<<s<<'\n';
return 1;
}
/*int main()
{
table["pi"]=3.1415926535897932385;
table["e"]=2.7182818284590452354;
while(cin)
{
get_token();
if(cur_tok==END)
break;
if(cur_tok==PRINT)
continue;
cout<<expr(false)<<'\n';
}
return no_of_errors;
}*/
double Calculator::Eval()
{
bool result;
int i=0;
while(i<expr.size())
{
get_token(i);
if(cur_tok==END)
break;
if(cur_tok==PRINT)
continue;
result=Expr(false,i);
}
return result;
}
void Calculator::Get(string str,istream &is)
{
cout<<str;
string exp;
if(is.peek()!='\n')
{
getline(is,exp);
expr=exp;
defined=true;
}
//is.ignore(INT_MAX,'\n');
}
void Calculator::Show(ostream &os)
{
os<<expr;
}
Main
#include <iostream>
#include <string>
#include <map>
using namespace std;
#include "Calc.h"
int main()
{
double x;
//table["pi"]=3.1415926535897932385;
//table["e"]=2.7182818284590452354;
Calculator c;
c.Get("Enter an expression\n",cin);
c.Show(cout);
x=c.Eval();
cout<<"result="<<x<<'\n';
return 0;
}