creating an expression using numbers and charater operator - c++

I am trying to create and expression from two or more numbers and character operator. The exact scenario is that i have two number for eg.
float a = 10.1, b = 10.2;
and a character operator
char ch = '+';
Now i have to create an expression that would look like
float c = 10.1 '+' 10.2;
i.e. i want to apply the operator mentioned in char variable "ch" between the two float numbers i have. So in this case the charater is '+' so i want to create the expression where both the float values will be added, if '-' then substraction etc. All the values will actually be supplied by the user so want to create an expression and than perform the operation.
Now one solution I thought of is to have switch case for different operators and that would do the trick. Another one is below:
float a = 10.1, b = 20.3;
char ch = '+';
string result = "";
ostringstream os;
os << a;
result += os.str();
os.str("");
os << b;
result += ch + os.str();
Now I wrote the above snippet so that I can create the expression based on user input and than return that expression so that it can be evaluated it in another procedure.
I am not sure if that's possible. I mean the switch case solution seems to be fine where i evaluate the expression here itself and return the output value, but just wanted to know if there is a way to return the expression to another function and then evaluate it there?
In tcl scripting language we have a command "expr" which does the same job and so was wondering if we have any such ability to do the same in c++. Any help would be appreciated.

I think the key to your question is in considering the expression as an object. You're using C++, which some consider an object-oriented programming language, right? :) Consider writing a class Expression that follows the Composite Pattern. An Expression might be just a simple value:
Expression(10.1)
It could also represent the addition of two subordinate Expressions:
Expression(Expression(10.1) + Expression(20.3))
Or to give you a further hint:
Expression('+', Expression(10.1), Expression(20.3))
Make Expression hold the operators and operands of the expression without actually evaluating it. Then you are free to construct it in one place in your program, then pass that to another place to actually evalute it.

C++ has a wealth of expression parsing libraries. While I haven’t used any of them myself I have heard good things about muParser.

Assuming that this is another assignment/homework and you don't pursue fully featured expression parser, here is the solution as simple as it could be:
#include <iostream>
#include <sstream>
using std::stringstream;
using std::cout;
using std::endl;
float compute(float a, float b, char op) {
switch(op) {
case '+':
return a + b;
case '-':
return a - b;
// You may add more operations in the similar way.
default:
cout << "Operation is not supported." << endl;
}
return 0;
}
int main() {
// These guys are here to simulate user input.
float input_a = 10.1;
float input_b = 20.3;
char input_op = '+';
stringstream ss;
ss << input_a << input_op << input_b;
// If you really make it interactive, then the program actually starts here.
float a;
float b;
char op;
// You simply read operands and operator from some input stream,
// which in case of interactive program could be `std::cin`.
ss >> a;
ss >> op;
ss >> b;
// Print the result of computation.
cout << compute(a, b, op) << endl;
}
If you want to handle more complex situations, like evaluation of nested expressions, possibly including parentheses functionality, then I'd suggest that you read first 4 chapters of the classical Dragon Book. It really took me around 1-2 weeks to be able to write LR-parser for ANSI C, which is somewhat much more complicated than your problem.
Your task is very simple and can be described with a toy context-free grammar which doesn't even require LL-parser to handle. Anyway to understand, why and how, I encorage you to read this book.

Related

Switch Case in c++ [duplicate]

This question already has answers here:
C/C++: switch for non-integers
(17 answers)
Closed 9 years ago.
How can I compare an array of char in c++ using switch-case?
Here is a part of my code:
char[256] buff;
switch(buff){
case "Name": printf("%s",buff);
break;
case "Number": printf("Number "%s",buff);
break;
defaul : break
}
I receive the error :" error: switch quantity not an integer".How can I resolve it?
If you really need a switch statement, you will need to convert your buff variable to an integer. To do so, you could use a hash function or a std::map.
The easy approach would be to make a std::map<std::string,int> containing the keys you want to use in the switch associated with unique int values. You would get something like:
std::map<string,int> switchmap;
...
switch(switchmap.find(std::string(buff))->second){
...
}
The std::map approach is very readable and shouldn't cause much confusion.
You just can't use an array as the expression in a switch construct.
In C++ case statements require a constant integer value and cannot be used with values calculated at runtime. However if you are using C++11 you can use a constexpr function to generate case values simulate using strings with a case statement.
This uses a hash function that takes a pointer to a string and generates a value at compile time instead of runtime. If more than one string generates the same value (a hash collision) you get the familiar error message about multiple case statements using the same value.
constexpr unsigned int djb2Hash(const char* str, int index = 0)
{
return !str[index] ? 0x1505 : (djb2Hash(str, index + 1) * 0x21) ^ str[index];
}
The djb2Hash function can then be used directly in both the switch and case statements. There is one caveat however, the hash function can result in a collision at runtime. The probability of this happening is driven primarily by the quality of the hash function. The solution presented here does not attempt to address this problem (but may in the future).
void DoSomething(const char *str)
{
switch(djb2Hash(str))
{
case djb2Hash("Hello"): SayHello(); break;
case djb2Hash("World"): SayWorld(); break;
}
}
This works very well but might be considered ugly. You can simplify this further by declaring a user defined literal that handles invoking the hash function.
// Create a literal type for short-hand case strings
constexpr unsigned int operator"" _C ( const char str[], size_t size)
{
return djb2Hash(str);
}
void DoSomething(const char *str)
{
switch(djb2Hash(str))
{
case "Hello"_C: SayHello(); break;
case "World"_C: SayWorld(); break;
}
}
This provides a more intuitive usage of strings in a switch statements but may also be considered slightly confusing because of the user defined literal.
[Edit: Added note about runtime hash collisions. Much Kudos to R. Martinho Fernandes for bringing it to my attention!]
You cannot use a non-integral type in a switch statement. Your problem would require something like:
char buff[256];
if(!strcmp(buf, "Name") printf("%s",buff);
if(!strcmp(buf, "Number") printf("%s",buff);
To get the results you are looking for - basically a bunch of if statements to replace the switch.
You are trying to do something we all dearly wish we could, but not in C/C++ :) The case in a switch statement must be integral values. One easy alternative is to have an enumeration that matches the set of strings you want to act on.
In C++ you can use a switch-case only with integers (char, int, ...) but not with c-strings (char *)
In your case you have to use a if-then-else construct
if (strcmp(buff, "Name") == 0) {
...
} else if (...) {
...
}
As the error says, switch only works for integers. The simplest resolution is to use a chain of if...else if... tests.
However, using a char array rather than a string is awkward, since you need quirky C-style functions to compare them. I suggest you use std::string instead.
std::string buff;
if (buff == "Name") {
// deal with name
} else if (buff == "Number") {
// deal with number
} else {
// none of the above
}
More complex approaches, perhaps mapping strings to numbers for use in a switch or to functors to call, are possible and may be more efficient if you have a huge number of cases; but you should get the simple version working before worrying about such optimisations.
Unlike many other languages that allow string and other object comparisons to be used in a switch-case, c++ requires that the underlying value be an integer. If you want use more complex object types, you will have to use an if else-if construct.
You can't use a switch directly for this situation.
Typically, you'd want to use a std::map (or std::unordered_map) to store the action to associate with each input. You might (for example) use a std::map<std::string, std::function>, and then store the addresses of functions/function objects in the map, so your final construct would be something like:
std::map<std::string, std::function> funcs;
funcs["Name"] = [](std::string const &n) {std::cout << n;};
funcs["Number"] = [](std::string const &n) {std::cout << "Number: " << n;};
// ...
auto f = funcs[buff];
f(buff);
// or combine lookup and call: funcs[buff](buff);
Two notes: first, you probably really want to use map::find for the second part, so you can detect when/if the string you're looking for isn't present in the map.
Second, as it stands, your code doesn't seem to make much sense -- you're both switching on buff and printing out buff's value, so (for example) if you buff contains Number, your output will be "Number Number". I'd guess you intend to use buff and some other variable that holds the value you care about.
You can partially do a "string" compare.
The below does not specifically satisfy your query (as C won't ride that pony), nor is it elegant code, but a variation on it may get you through your need. I do not recommend you do this if you a learning C/C++, but this construct has worked well in limited programming environment.
(I use it in PIC programming where strlen(buff)==1 or 2 and sizeof(int)==2.)
Let's assume sizeof(int) == 4 and strlen(buff) >= 3.
char buff[256];
// buff assignment code is TBD.
// Form a switch 4-byte key from the string "buff".
// assuming a big endian CPU.
int key = (buff[0] << 3*8) | (buff[1] << 2*8) | (buff[2] << 1*8) | (buff[3] << 0*8);
// if on a little endian machine use:
// int key = (buff[0] << 0*8) | (buff[1] << 1*8) | (buff[2] << 2*8) | (buff[3] << 3*8);
switch (key) {
// Notice the single quote vs. double quote use of constructing case constants.
case 'Name': printf("%s",buff); break;
case 'Numb': printf("Number \"%s\"",buff); break;
default : ;
}

Prefix(polish) notation - evaluation c++

I am looking for code wchich parses prefix expressions using recursion. Primarily in C++, but it can bee in other language, i will translate. Thanks.
It's really easy to do yourself (you just need a stack for the operators (and sometimes/optionally its first term)).
But if you really don't want to do much work, here's a link:
prefix notation string to int conversion
If you need to use recursion, you basically use local variables in the function as individual elements in your stack.
Eg. pseudo-C++ code follows:
int naughtyglobalendindex = 0;
int parse(string str) {
if (/* str starts off with an integer */) return the integer;
char operator;
operator = ?? // you will need to get the first op here. Maybe sscanf(str,"%c",&operator) or similar
// get first argument
int first = parse(/* str with 1st operator removed */);
// get 2nd integer argument
int second = parse(/* str - get substring from naughtyglobalendindex to end*/)
// return first operator second <- this is pseudocode
// in effect you want a switch clause
switch (operator) {
case '+': return first + second;
case '-': return first - second; // and so on
}
}
You can convert the pseudocode to actual C++, and if you want, fix the global naughtyglobalendindex variable if you want.

Extract items in an arithmetic expression in c/c++

If I have an arithmetic expression like x+y-12 / z in a string (c-style or otherwise) in c or c++, how can I extract one item at a time (including the operator)? There may or may not be a space in the expression and multiple digits are allowed for constants.
If your input is simple you can start with something like this:
typedef struct token {
int type;
int ival;
char sval[256];
int ssize;
} Token;
char *get_next_tok(char *buffer, Token *token) {
char *p = buffer; while (isspace(*p)) p++; // trim
if (my_isopchar(*p)) // checks -+*...
p=my_get_op(p, token); // a function to handle multi-char ops
else if (isdigit(*p)) {
token->ival=strtol(p, &p, 10);
token->type=TK_CONST;
}
else if (isalpha(*p)) {
while (isalpha(*p)) {
token->sval[token->ssize++] = *p; p++;
}
token->type = TK_VAR;
}
return p;
}
Easy way: strtok
Hard way: Flex+Bison
Look into parsing. What you describe can, in fact, be quite easily implemented using regular expressions, or hand-written parsing. Think of what makes up your expression's individual tokens, and how code to extract the next token would look.
There was a very nice tutorial on Flipcode on implementing scripting engines. You can read a few of the first chapters.
Basically you need to implement a lexical analyzer which breaks the string into tokens (identifier / constant / operator) and from tokens you can create a parse tree or reverse Polish notation e.g. by recursive descent or using a LL parser which is rather elegant if you are only interested in parsing arithmetic expressions.
Reverse Polish notation is then evaluated using stack-based interpreter or parse tree is evaluated using a recursive algorithm.
I have written a small expression evaluation class in C++ which supports simple expressions with variables.

string input, how to tell if it is int?

I am writing a program that converts a parathensized expression into a mathematical one, and evaluates it. I've got the calculation bit written already.
I am using a stack for the operands, and a queue for the numbers. Adding operands to the stack isn't an issue, but I need to identify whether the input character is an integer, and if so, add it to the queue. Here's some code:
cout << "Enter the numbers and operands for the expression";
string aString;
do
{
cin >> aString
if (aString = int) // function to convert to read if int, convert to int
{
c_str(...);
atoi(...);
istack.push(int);
}
}
That's where I'm stuck now. I know I'm going to have to use c_str and atoi to convert it to an int. Am I taking the wrong approach?
Use the .fail() method of the stream.
If you need the string too, you can read to a string first, then attempt to convert the string to an integer using a stringstream object and check .fail() on the stringstream to see if the conversion could be done.
cin >> aString;
std::stringstream ss;
ss << aString;
int n;
ss >> n;
if (!ss.fail()) {
// int;
} else {
// not int;
}
I'll probably get flamed for this by the C++ purists.
However, sometimes the C++ library is just more work than the C library. I offer this
solution to C developers out there. And C++ developers who don't mind using some of the
features of the C library.
The whole check and conversion can be done in 1 line of C using the sscanf function.
int intval;
cin >> aString
if (sscanf(aString.c_str(), "%d", &intval)){
istack.push(intval);
}
sscanf returns the number of input arguments matched and assigned. So in this case, it's looking for one standard signed int value. If sscanf returns 1 then it succeeded in assigning the value. If it returns 0 then we don't have an int.
If you expect an integer, I would use boost::lexical_cast.
std::string some_string = "345";
int val = boost::lexical_cast<int>(some_string);
If it fails to cast to an integer, it will throw. The performance is pretty reasonable, and it keeps your code very clean.
I am unaware of any non-throwing version. You could use something like this, though I usually try to avoid letting exceptions control program flow.
bool cast_nothrow(const std::string &str, int &val) {
try {
val = boost::lexical_cast<int>(str);
return true;
} catch (boost::bad_lexical_cast &) {
return false;
}
}
Edit:
I would not recommend your integer validation checking for structure like you described. Good functions do one thing and one thing well.
Usually you'd want a more formal grammar parser to handle such things. My honest advice is to embed a scripting language or library in your project. It is non-trivial, so let someone else do the hard work.
If I actually tried to implement what you propose, I would probably do a stack based solution keeping the parenthesis levels at their own stack frame. The simplest thing would just be to hard code the simple operators (parenthesis, add, sub, etc) and assume that the rest of everything is a number.
Eventually you'd want everything broken down into some expression type. It might look something like this:
struct Expression {
virtual ~Expression() {}
virtual float value() const = 0;
};
struct Number : public Expression {
virtual float value() const {return val;}
float val;
};
struct AdditionOper : public Expression {
virtual float value() const {return lhs->value() + rhs->value();}
boost::shared_ptr<Expression> lhs;
boost::shared_ptr<Expression> rhs;
};
I'd start by parsing out the parenthesis, they will determine the order of your expressions. Then I'd split everything based on the numerical operands and start putting them in expressions. Then you're left with cases like 3 + 4 * 6 which would require some some care to get the order of operations right.
Good luck.
You can either run your function that converts a string representation of a number to a double and see if there's an error, or you can look at the contents of the string and see if it matches the pattern of a number and then do the conversion.
You might use boost::lexical_cast<double>() or std::stod() (C++11) where errors are reported with an exception, or istringstream extractors where the error is reported by setting the fail bit, or with C conversion functions that report errors by setting the global (thread local, rather) variable errno.
try {
istack.push_back(std::stod(aString));
} catch(std::invalid_argument &e) {
// aString is not a number
}
or
errno = 0;
char const *s = aString.c_str();
char *end;
double result = strtod(s,&end);
if(EINVAL==errno) {
// the string is not a number
} else {
istack.push_back(result);
}
An implementation of the second option might use a regex to see if the string matches the pattern you use for numbers, and if it does then running your conversion function. Here's an example of a pattern you might expect for floating point values:
std::regex pattern("[+-]?(\d*.\d+|\d+.?)([eE][+-]?\d+)?");
if(std::regex_match(aString,pattern)) {
istack.push_back(std::stod(aString));
} else {
// aString is not a number
}
Also, this probably doesn't matter to you, but most any built in method for converting a string to a number will be locale sensitive one way or another. One way to isolate yourself from this is to use a stringstream you create and imbue with the classic locale.
I guess the C++ (no boost) way would be this :
do
{
std::stringstream ss;
std::string test;
cin >> test;
ss << test;
int num;
if (ss >> num) // function to convert to read if int, convert to int
{
std::cout << "Number : " << num << "\n";
}
}while(true); // don't do this though..
Can you not use ctype.h http://www.cplusplus.com/reference/clibrary/cctype/. I have used this before and did not get into trouble.
Especially if you're doing base-10 input, I find the most blatant thing to do is read the string, then check that it only contains valid characters:
string s;
cin >> s;
if(strrspn(s.c_str(), "0123456789")==s.length()){
//int
} else{
//not int
}

Malfunctioning type-casting of string to unsigned int

I'm having a annoying problem with a C++ function that I wrote and whose purpose is to validate de user input. The function reads the user input, verifies if it's a number and, if so, if it is in the range [min, max].
The problem occurs when I invoke the template function with a unsigned type, like size_t, and the input is a negative number. The string stream converts the string to something like 4294967291. I can see that the program is converting the data to a value near de maximum value of the unsigned data type (defined in the numeric_limits header) but my question is why, since the if statement should stop at sstream >> value?
My code:
template <class T>
T getNumberInput(std::string prompt, T min, T max) {
std::string input;
T value;
while (true) {
try {
std::cout << prompt;
std::cin.clear();
std::getline(std::cin, input);
std::stringstream sstream(input);
if (input.empty()) {
throw EmptyInput<std::string>(input);
} else if (sstream >> value && value >= min && value <= max) {
std::cout << std::endl;
return value;
} else {
throw InvalidInput<std::string>(input);
}
} catch (EmptyInput<std::string> & emptyInput) {
std::cout << "O campo não pode ser vazio!\n" << std::endl;
} catch (InvalidInput<std::string> & invalidInput){
std::cout << "Tipo de dados inválido!\n" << std::endl;
}
}
}
Thank you for your time!
In C++ arithmetic involving an unsigned type with n value bits, is guaranteed to be modulo 2^n. That means any result is wrapped back into the range 0 through 2^n-1, by adding or subtracting a suitable multiple of 2^n. This is so also in C.
So you need to check the input for minus sign, or add some other check.
By the way, your if with >> and && produced some effect on my bad-code-meter. I can never remember the operator precedences for >> versus &&. I guess if it compiled it must be OK, though, since >> can't take a value right-hand-side. Checking... OK, but I'd use parentheses to clarify that.
Also, on the code structure, it would be a good idea to separate the interactive input thing from the checking of the input. E.g., can you use any of that code in a GUI program, with input from an edit field? No, not as it is...
Cheers & hth.,
Alf has already answered this, but I had a couple of other thoughts.
Pull the code that gets the input out of the try block. You're not catching any exceptions that it might throw, so it doesn't communicate the intent as well. The try block should start right before the if (input.empty())...
Then pull all of the stuff in the try block into a single validate function. This cleans up the code here. For use in a GUI, though, you would want to create a function that just gets the input without validation and expose the validation function. Then the user could handle the validation exceptions as needed. Although in this case, I don't see an advantage to using exceptions as opposed to simple error codes for the validation.
Hope this helps,