How to add multi digit integers in a reverse polish calculator - c++

// FILE: calc.h
#include <iostream>
#include <stack> // Uses STL
#include <string> // Uses STL
using namespace std;
void evaluate_stack_tops(stack<double> & numbers, stack<char> & operations);
double read_and_evaluate(string line)
{
const char RIGHT_PARENTHESIS = ')';
stack<double> numbers; // local stack object
stack<char> operations; // local stack object
double number;
char symbol;
size_t position = 0;
while (position < line.length())
{
if (isdigit(line[position]))
{
number = line[position++] - '0'; // get value
numbers.push(number);
}
else if (strchr("+-*/", line[position]) != NULL)
{
symbol = line[position++];
operations.push(symbol);
}
else if (line[position] == RIGHT_PARENTHESIS)
{
position++;
evaluate_stack_tops(numbers, operations);
}
else
position++;
}
if (!operations.empty())
evaluate_stack_tops(numbers, operations);
return numbers.top();
}
void evaluate_stack_tops(stack<double> & numbers, stack<char> & operations)
{
double operand1, operand2;
operand2 = numbers.top();
numbers.pop();
operand1 = numbers.top();
numbers.pop();
switch (operations.top())
{
case '+': numbers.push(operand1 + operand2); break;
case '-': numbers.push(operand1 - operand2); break;
case '*': numbers.push(operand1 * operand2); break;
case '/': numbers.push(operand1 / operand2); break;
}
operations.pop();
}
// FILE: Use_Stack.cpp
#include <iostream>
using namespace std;
#include "calc.h"
int main()
{
double answer;
string line;
cout << "Type a fully parenthesized arithmetic expression (SINGLE DIGITS ONLY!):\n";
getline(cin, line);
answer = read_and_evaluate(line);
cout << "That evaluates to " << answer << endl;
system("pause");
return 0;
}
Everything works and i can input simple things like "2 4 3 * + 7 – 2 +" but if i wanted to input something like "123 60 +" it would not work. i separated it in two header files. Can someone give me a hint on how to accept multi-digit integers?

One way to solve the problem is where you discover an number, instead of assuming it is only one digit long, use a loop to collect all the other digits that are part of the number. The loop would terminate when it encounters a non-digit, or a space.
A better way to do it would be to tokenize the input string using stringstream. In this scenario, you would put the entire line of input into a string and then use a while loop similar to the following:
stringstream ss(line);
string token;
while (ss >> token) {
// do stuff with token
}

RPN works by having a stack of values which you manipulate. Given input "13", the manipulation needed to go from top=1 to top=13 is fairly straightforward: top = 10 * top + digit

Related

Infix/postfix/prefix program. Want to print a result using my printResult() function. Need help getting an output

My problem is I don't know how to get anything to output from here. I want to print the postfix result so far using printResult().. how can I do this? I am not sure how to cout the result I am getting inside my inToPost() function which should be the result of converting to postfix. Thanks.
#include <iostream>
#include <fstream>
#include <stack>
#include <string>
using namespace std;
class Expression{
public:
string inToPost();
string convertThis; // Expression that we want converted
Expression(string input, int direction); //constructor
bool isOperator(char character);
bool isOperand(char character);
int isHigherWeight(char character);
bool isHigherPrecedence(char op1, char op2);
string printResult();
private:
string infix;
string postfix;
string prefix;
};
//Constructor function
Expression::Expression(string input, int direction){
switch (direction){
case 1: infix = input;
case 2: postfix = input;
case 3: prefix = input;
}
}
//Operator Function checks to see if character is a legal symbol
bool Expression::isOperator(char character){
if((character == '*')||(character == '+')||(character == '-')||(character == '/'))
return true;
else
return false;
}
//Operand Function checks to see if character is a legal character
bool Expression::isOperand(char character){
if(character >= 'a' && character <= 'z')
return true;
if(character >= 'A' && character <= 'Z')
return true;
if(character >= '0' && character <= '9')
return true;
else
return false;
}
//Function determines the weight of Operator.
int Expression::isHigherWeight(char character){
int weight = 0; // or -1?
switch(character){
case '+':
case '-':
weight = 1;
case '*':
case '/':
weight = 2;
}
return weight;
}
//Function that compares weights of two different Operators.
bool Expression::isHigherPrecedence(char oper1, char oper2){
int op1Weight = isHigherWeight(oper1);
int op2Weight = isHigherWeight(oper2);
// If operators have equal precedence, return true
// return false
return op1Weight > op2Weight ? true: false;{
}
}
string Expression::inToPost(){
stack<char> Stack;
string postfix = ""; // Initialize postfix as empty string.
for(int i = 0;i< convertThis.length();i++){ //go through array of string convertThis
if (convertThis[i] == '('){ //1-Read the left parenthesis and push it onto the stack
Stack.push(convertThis[i]);
}
else if(isOperand(convertThis[i])){ //2-else if( the next input is a number or letter)
cout << convertThis[i]; //3-Read the operand and write it to the output
}
else if(isOperator(convertThis[i])){ //4-else if the next input is operator
cout << Stack.top();
Stack.pop(); //5-Print the top operation and pop it
}
//6-
while(!Stack.empty() && Stack.top() != '(' && isHigherPrecedence(Stack.top(),convertThis[i])){
Stack.push(convertThis[i]); //7- Read the next input symbol, and push this symbol onto the stack
}
// 8- Read and discard the next input symbol(which should be a right parenthesis).
if (convertThis[i] == ')'){
i+1;
// 9- Print the top operation and pop it; Keep printing and popping until
while (!Stack.top() == '('){
cout << Stack.top();
Stack.pop();
}
}
Stack.pop(); //10- Finally, pop the left parenthesis.
while(!Stack.empty()){
cout << Stack.top();
}
return postfix;
}
}
string Expression::printResult(){
return postfix;
}
int main(){
string convertThis;
int choice;
cout << "|-----Here is my conversion menu-----|" << endl;
cout << "|----What are you converting to?-----|" << endl << endl;
cout << "1- Infix to postfix" << endl;
cout << "2- Infix to prefix" << endl;
cout << "3- postfix to infix?" << endl;
cout << "4- prefix to infix?" << endl;
//cin >> choice;
//cin.ignore();
cout << "Now enter the expression you want to convert ";
getline(cin,convertThis);
//Expression printResult;
//cout << printResult.printResult();
}
Your question is far too complicated to be asking "How do I send output to the screen?" You have 10 functions in a class...a class that you never used in main. Half the functions are empty...Start smaller. Start with a class that has a private string variable, a constructor that takes a string and a single public function to display that string.
It will look something like this...
#include <string>
#include <iostream>
class MyClass{
public:
MyClass(std::string str) : m_string(str){}
void PrintString() { std::cout << m_string << std::endl; }
private:
std::string m_string;
};
int main(int argc, char * argv[]){
std::string inputString("This is my test string.");
MyClass myClass(inputString); // create an instance of your class
myClass.PrintString(); // Print the variable within your class
return 0;
}
Once you have that working add a second input to the constructor for your 4 options. There are many ways to do this. Then one by one add the remaining functions and test them.

Distinguishing between an int and a double

I've searched for this answer, and no one seems to know how to fix this error. I want the input to be strictly an int. If the input is a double, I want it to send an error.
int creatLegs = 0;
string trash;
bool validLegs = true;
do
{
cout << "How many legs should the creature have? ";
cin >> creatLegs;
if(cin.fail())
{
cin.clear();
cin >> trash; //sets to string, so that cin.ignore() ignores the whole string.
cin.ignore(); //only ignores one character
validLegs = false;
}
if (creatLegs > 0)
{
validLegs = true;
}
if (!validLegs)
{
cout << "Invalid value, try again.\n";
}
} while (!validLegs);
It seems to almost work. It sends the error, but only after moving onto the next loop. How can I fix this? And why is it still showing the error message but still moving on before showing it?
An input can be something else than a representation of an integer or of a floating point number.
Remember that numbers are not their representation(s): 9 (decimal), 017 (octal, à la C), 0b1001 (binary, à la Ocaml), IX (Roman notation), 8+1 (arithmetic expression), neuf (French) are all representations of the same number nine.
So you have to decide if you accept an input like 9 x, or 9 (with several spaces after the digit), ... More generally you have to define what are the acceptable inputs (and if the input is ending at end of line or not, if spaces or punctuation should be accepted, etc...).
You could read an entire line (e.g. with std::getline) and use e.g. sscanf (where the %n control format is useful, and so is the item count returned by sscanf) or std::stol (where you use the end pointer) to parse it
Notice also that the phrasing of your question ("Distinguishing between an int and a double") is wrong. There is no single "int or double" type in C++ (but int is a scalar type, and double is a scalar type in C++, and you could define a class with a tagged union to hold either of them). AFAIU, if you declare int x; then use std::cin >> x; with the user inputting 12.64 the dot and the digits 64 after it won't be parsed and x would become 12.
I think that you should read data as string, and then check it char by char to verify that it is integer - if every char is a digit, then we have integer and we can parse it.
Problem with streams is, that if you're trying to read integer but decimal is passed, it reads the number up to the dot. And this part is a proper integer, so cin.fail() returns false.
Sample code:
#include <iostream>
#include <string>
#include <cctype>
#include <cstdlib>
using namespace std;
int main() {
int creatLegs = 0;
bool validLegs = true;
do
{
cout << "How many legs should the creature have? ";
string input;
getline(cin, input);
validLegs = true;
for (string::const_iterator i = input.begin(); validLegs && i != input.end(); ++i) {
if (!isdigit(*i)) {
validLegs = false;
}
}
if (!validLegs)
{
cout << "Invalid value, try again.\n";
} else {
creatLegs = atoi(input.c_str());
}
} while (!validLegs);
cout << creatLegs << endl;
}
This of course is not a perfect solution. If there any leading or trailing spaces (or any other characters like + or -), the program will fail. But you always can add some code to handle those situations, if you need to.
int creatLegs = 0;
do
{
cout << "How many legs should the creature have? ";
cin >> creatLegs; // trying to get integer
if(!cin.fail()) // if cin.fail == false, then we got an int and leave loop
break;
cout << "Invalid value, try again.\n"; // else show err msg and try once more
cin.clear();
} while (1);
This question already has an accepted answer, however I'll contribute a solution that handles all numbers that are integral, even those that are expressed as a floating point number (with no fractional part) and rejects input that contains anything other than spaces following the number.
Examples of accepted values, these all represent the number 4:
4
4.
4.0
+4
004.0
400e-2
Examples of rejected values:
3.999999
4.000001
40e-1x
4,
#include <iostream>
#include <sstream>
#include <cctype>
#include <string>
using namespace std;
bool get_int( const string & input, int & i ) {
stringstream ss(input);
double d;
bool isValid = ss >> d;
if (isValid) {
char c;
while( isValid && ss >> c ) isValid = isspace(c);
if (isValid) {
i = static_cast<int>(d);
isValid = (d == static_cast<double>(i));
}
}
return isValid;
}
int main( int argc, char *argv[] )
{
int creatLegs = 0;
bool validLegs = false;
do
{
string line;
do {
cout << "How many legs should the creature have? ";
} while (not getline (cin,line));
validLegs = get_int( line, creatLegs );
if (creatLegs <= 0)
{
validLegs = false;
}
if (not validLegs)
{
cout << "Invalid value, try again." << endl;
}
} while (not validLegs);
cout << "Got legs! (" << creatLegs << ")" << endl;
return 0;
}
If you want strictly integers (no decimal period and no scientific notation) then use this simpler get_int function:
bool get_int( const string & input, int & i ) {
stringstream ss(input);
bool isValid = ss >> i;
if (isValid) {
char c;
while(isValid && ss >> c) isValid = isspace(c);
}
return isValid;
}

C++ I can't compare char variable to values [duplicate]

This question already has answers here:
Single quotes vs. double quotes in C or C++
(15 answers)
Closed 4 years ago.
Have to do this for the first cs course I'm taking. It's a basic calculator that takes an operator and a value and calculates the total (total beginning at 0).
#include <iostream>
using namespace std;
int main()
{
char oprtr;
float value, total = 0.0;
cin >> oprtr >> value;
while (oprtr != "q")
{
if (oprtr == "+")
total += value;
else if (oprtr == "-")
total -= value;
}
}
It's not finished but already having issues with it. It gives errors saying something along the lines of "prohibits comparing char values to int values"
Double quotes ("q") are for strings. Single quotes ('q') are for characters.
So:
while (oprtr != 'q')
{
if (oprtr == '+')
total += value;
else if (oprtr == '-')
total -= value;
}
Char means Character and you must use single quotes '' for these, double quotes "" are for strings.
The reason you are getting this error is because you're attempting to compare a character to a string literal (a const char), the exact error you're getting will be:
Operand types are incompatible ("char" and "const char").
The below code will fix this error:
#include <iostream>
using namespace std;
int main()
{
char oprtr;
float value, total = 0.0;
cin >> oprtr >> value;
while (oprtr != 'q')
{
if (oprtr == '+')
total += value;
else if (oprtr == '-')
total -= value;
}
}
And also, since you are reading the statement or the expression once, there is no need for you to loop while the character is not equal to 'q'. You should basically perform one operation. Also, switch is a very useful construct for comparing literals instead of several if's. So I would simplify that as.
#include <iostream>
using namespace std;
int main(){
char op;
float value, total = 0.0;
cin >> op >> value;
//it is important at this stage to check for errors, as they are most likely
//to occur.
if(!cin){
cerr << "Error: format unknown! \n"; //basic error handled here, the prog outputs the error
}
//now perform the calculation
switch(op){
case '+': total += value;
break;
case '-' : total -= value;
break;
case 'q' : break; //i presume q is your quit character
default: /*unknown character*/ cerr << "Unknown operation! \n";
}
cout << "Total: "<<total << endl;
return 0;
}
this basically reads in one expression and add it to the total. You can modify it to read as long as you want.
Comparing string length is a common function in C programming, as it allows you to see which string contains more characters. This is very useful for sorting data. Comparing strings requires a special function; do not use != or ==.
http://www.techonthenet.com/c_language/standard_library_functions/string_h/strcmp.php

RPN calculator doesn't perform calculations correctly

I have a program that is supposed to convert an expression into reverse polish notation, and then display the answer after performing the calculations. Right now it doesn't perform calculations correctly. For example, if I enter 5+2+5, it only registers the 5+2 for some reason. Can anyone tell me what I did wrong?
#include <iostream>
#include <stack>
void calculation(int, int, char);
using namespace std;
stack<int> a;
void main(void)
{
bool expression = false;
char ch;
char done;
int op1, op2;
cout << "Reverse Polish Notation : " << endl;
cout << "Enter expression: " << endl;
while (!expression)
{
cin >> op1;
cin >> op2;
cin >> ch;
calculation(op1, op2, ch);
if (!cin)
expression = false;
else
{
expression = true;
calculation(op1, op2, ch);
}
}
cout << "Your expression is " << a.top() << endl;
}
void calculation(int oper1, int oper2, char chr)
{
switch (chr)
{
case '+':
a.push(oper1 + oper2);
break;
case '-':
a.push(oper1 - oper2);
break;
case '*':
a.push(oper1 * oper2);
break;
case '/':
a.push(oper1 / oper2);
break;
}
}
Your program does not convert anything. It is a very simple RPN calculator that takes a single term consisting of two operands and a binary operation and calculate the results.
If you need it to take more complex RPN inputs, you need to re-design the input and calculation logic.
If you want to input infix expressions like 5+4 but keep the internal representation as an RPN-stack, you will also have to write a parser which does that.
All operations should be to and from the stack. Your main loop should look more like
while not eol
if reading an operator
push result of applying operator to top two stack elements
else if reading an integer
read it and push it on to the stack
else
print an error message
print value at top of stack
I omitted a pile of stack depth checks.

Stack around the variable 'equation' was corrupted

I'm trying to make a calculator in VC++ and even though it runs, it keeps reading memory that I haven't told it to, and I don't know how to make it stop.
#include <iostream>
#include <ctype.h>
int main(){
char equation[4];
equation[3] = '\0'; //string terminator
int result;
bool wantsToContinue = true;
char yesOrNo;
equationPrompt:
std::cout << "Enter Equation: ";
std::cin >> equation;
while(wantsToContinue){
switch(equation[1]){
case '+':
result = int(equation[0]) + int(equation[2]);
break;
case '-':
result = int(equation[0]) - int(equation[2]);
break;
case '*':
result = int(equation[0]) * int(equation[2]);
break;
case '/':
result = int(equation[0]) / int(equation[2]);
break;
}
std::cout << std::endl << "Your answer is " << result << std::endl;
exitPrompt:
std::cout << "Exit? Y/N: ";
std::cin >> yesOrNo;
if(tolower(yesOrNo) == 'n'){
wantsToContinue = true;
goto equationPrompt;
}
else if (tolower(yesOrNo) == 'y')
wantsToContinue = false;
else{
std::cout << std::endl << "Unknown response." << std::endl;
goto exitPrompt;
}
}
return 0;
}
You make it stop by not writing an arcane Frankenstein language mix of C and C++, but instead using real C++ string types:
#include <string>
#include <istream>
#include <iostream>
int main()
{
std::string equation;
std::cin >> equation;
// now equation[0] is the first character
}
Note that int(equation[0]) is almost guaranteed not to be what you think. What you want is something like int x = std::atoi(equation[0]); or std::strtol(), but that only works for single digits. Probably much simpler to just stream into an integer, which performs an actual text-to-integer conversion:
int x, y;
std::string operand;
std::cin >> x >> operand >> y;
equation is an array of 4 chars.
std::cin >> equation;
reads an arbitrarily long string into that array. Type too much, and it will overflow, stepping on adjacent memory.
As #Kerrek SB says, you're better off using std::string, which doesn't have that problem.