Andy M
Andy M

Reputation: 167

Arithmetic expression input calculation in c++

I always asked user to input x and y and then calculate the result. This is a very simple example :

int main()
{
int x,y;
cout << "Please enter x" <<endl;
cin >> x ;
cout << "please enter y" <<endl;
cin >> y;

int result = x + y ;
cout << result << endl;
return 0;
}

but what if the user inputs the full expression ? for example asking the user to input an expression and the user input : 4+5, can we calculate this directly and give the result?

Upvotes: 0

Views: 1982

Answers (3)

lhf
lhf

Reputation: 72312

Following up on Michael Anderson's answer, using my ae front-end for the Lua engine, the heart of the code would be simply

ae_open();
ae_set("x",x);
ae_set("y",y);
int result = ae_eval("x + y");
ae_close();

Of course, the fun part is when ae_eval gets a strings containing an arbitrary expression input from the user.

Upvotes: 1

Michael Anderson
Michael Anderson

Reputation: 73480

I would not spend time reinventing the wheel. I'd use an existing scripting language for the users input, and my personal choice there would be lua, though many others are feasible.

This is roughly what your application would look like using lua as an interpreter.

#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"

#include <string>
#include <iostream>


int main()
{
  using namespace std;
  string x,y;
  cout << "Please enter x" <<endl;
  cin >> x ;
  cout << "please enter y" <<endl;
  cin >> y;

  //TODO: You may want to check that they've entered an expression
  //
  lua_State * L = lua_open();

  // We only import the maths library, rather than all the available
  // libraries, so the user can't do i/o etc.

  luaopen_math(L);
  luaopen_base(L);

  // We next pull the math library into the global namespace, so that
  // the user can use sin(x) rather than math.sin(x).
  if( luaL_dostring(L,"for k,v in pairs(math) do _G[k] = v end") != 0)
  {
    std::cout<<"Error :"<<lua_tostring(L,-1)<<std::endl;
    return 1;
  }

  // Convert x to an integer
  x = "return "+x;
  if( luaL_dostring(L,x.c_str()) != 0 )
  {
    std::cout<<"Error in x :"<<lua_tostring(L,-1)<<std::endl;
    return 1;
  }
  int xv = lua_tointeger(L,-1);
  lua_pop(L,1);

  // Convert y to an integer
  y = "return "+y;
  if( luaL_dostring(L,y.c_str()) != 0 )
  {
    std::cout<<"Error in y :"<<lua_tostring(L,-1)<<std::endl;
    return 1;
  }
  int yv = lua_tointeger(L,-1);
  lua_pop(L,1);

  int result = xv + yv ;
  cout << result << endl;
  return 0;
}

With this you can enter things like 1+sin(2.5)*3.

Upvotes: 1

mert
mert

Reputation: 1000

You should implement infix notation parsing algorithm.

For example; http://en.wikipedia.org/wiki/Shunting-yard_algorithm

Upvotes: 0

Related Questions