how to make the calculator program loop after an unrecognized symbol is inputted
Dec 11, 2018 at 9:08pm UTC
I have a problem that I would like to fix. I wrote a program to take in an expression in infix notation and all the mathematical operations work, and if an unrecognized symbol gets inputted, the program outputs "Unrecognized symbol encountered. Please try again:". But after this, the program stops on its own and does not output "Enter a mathematical expression" How Can I fix this? Thank you
calculatorClass.h:
#pragma once
#include <iostream>
#include <stack>
#include <list>
#include <string>
#include <queue>
#include <cstdlib>
#include <cmath>
using namespace std;
namespace calc
{
struct data
{
double x;
char chars;
data()
{
chars = ' ';
x = 1;
}
};
class calculator
{
private:
int orderOfOperations(char chars);
void infixToPostfixPrivate();
void solvePrivate();
bool numbersPrivate(char chars);
bool bracketsPrivate(char chars);
public:
list<struct data> l;
queue<struct data> Q;
queue<struct data> P;
stack<char> temp;
stack<double> R;
calculator();
~calculator();
void infixToPostfix();
void solve();
bool numbers(char chars);
bool brackets(char chars);
int factorial(int x);
};
}
calculatorClass.cpp:
#include "calculatorClass.h"
#include <stack>
#include <list>
#include <string>
#include <queue>
#include <cstdlib>
#include <cmath>
using namespace std;
namespace calc
{
calculator::calculator()
{
}
calculator::~calculator()
{
}
int calculator::orderOfOperations(char chars)
{
switch (chars)
{
case '^':
{
return 4;
}
case 'v':
{
return 3;
}
case '/':
case '*':
case '!':
{
return 2;
}
case '+':
case '-':
{
return 1;
}
default:
{
return 0;
}
}
}
bool calculator::bracketsPrivate(char chars)
{
switch (chars)
{
case '+':
case '-':
case '/':
case '*':
case '!':
case '^':
case '(':
case ')':
case 'v':
{
return true;
}
default:
{
return false;
}
}
}
bool calculator::numbersPrivate(char chars)
{
if (chars == '.' || (int)chars >= 48 && (int)chars <= 57)
{
return true;
}
else
{
return false;
}
}
void calculator::infixToPostfixPrivate()
{
while (P.empty() == false)
{
struct data chars = P.front();
P.pop();
if (chars.chars == '(')
{
temp.push('(');
}
else if (chars.chars == ')')
{
while (1)
{
char ctemp = temp.top();
temp.pop();
if (ctemp == '(' || ctemp == '\0' || temp.empty() == true)
{
break;
}
else
{
struct data z;
z.chars = ctemp;
Q.push(z);
}
}
}
else if (chars.chars == '+' || chars.chars == '*' || chars.chars == '-' || chars.chars == '!' || chars.chars == '/' || chars.chars == '^' || chars.chars == 'v')
{
if (temp.empty() == false && orderOfOperations(temp.top()) <= orderOfOperations(chars.chars))
{
temp.push(chars.chars);
}
else
{
while (temp.empty() == false && orderOfOperations(temp.top()) > orderOfOperations(chars.chars))
{
struct data z;
z.chars = temp.top();
Q.push(z);
temp.pop();
}
temp.push(chars.chars);
}
}
else
{
Q.push(chars);
}
}
while (temp.empty() == false)
{
struct data z;
z.chars = temp.top();
Q.push(z);
temp.pop();
}
}
void calculator::solvePrivate()
{
while (Q.empty() == false)
{
struct data chars = Q.front();
Q.pop();
if (chars.chars == '+' || chars.chars == '*' || chars.chars == '-' || chars.chars == '/' || chars.chars == '^')
{
double operand2 = R.top();
R.pop();
double operand1 = R.top();
R.pop();
switch (chars.chars)
{
case '+':
{
operand1 += operand2;
break;
}
case '-':
{
operand1 -= operand2;
break;
}
case '*':
{
operand1 *= operand2;
break;
}
case '/':
{
operand1 /= operand2;
break;
}
case '^':
{
int x = operand1;
if ((int)operand2 == operand2)
{
for (register int i = 1; i < (int)operand2; ++i)
{
operand1 *= x;
}
}
else
{
operand1 = pow(operand1, operand2);
}
break;
}
}
R.push(operand1);
}
else if (chars.chars == '!' || chars.chars == 'v')
{
double operand1 = R.top();
R.pop();
switch (chars.chars)
{
case '!':
{
operand1 = operand1 * factorial(operand1 - 1);
break;
}
case 'v':
{
operand1 = sqrt(operand1);
break;
}
}
R.push(operand1);
}
else if (chars.chars == ' ')
{
R.push(chars.x);
}
}
}
int calculator::factorial(int x)
{
if (x > 1)
{
return x * factorial(x - 1);
}
else
{
return 1;
}
}
void calculator::infixToPostfix()
{
infixToPostfixPrivate();
}
void calculator::solve()
{
solvePrivate();
}
bool calculator::numbers(char chars)
{
return numbersPrivate(chars);
}
bool calculator::brackets(char chars)
{
return bracketsPrivate(chars);
}
}
finalProject.cpp:
#include "calculatorClass.h"
#include <iostream>
#include <stack>
#include <list>
#include <string>
#include <queue>
#include <cstdlib>
#include <cmath>
using namespace std;
using namespace calc;
int main()
{
while (2)
{
calculator calculate;
cout << "Enter a mathematical expression. This program includes addition, subtraction, multiplication, and division." << endl;
string str;
getline(cin, str, '\n');
char expression = 0;
while (expression < str.length())
{
if (str[expression] != ' ')
{
if (calculate.brackets(str[expression]) == true)
{
struct data temp;
temp.chars = str[expression];
calculate.l.push_back(temp);
++expression;
}
else if (calculate.numbers(str[expression]) == true)
{
string temp = "";
while (calculate.numbers(str[expression]) == true)
{
temp += str[expression];
++expression;
}
struct data temp1;
temp1.x = atof(temp.data());
calculate.l.push_back(temp1);
}
else
{
cout << "Unrecognized symbol encountered : \"" << str[expression] << "\"" << endl;
cout << "Please try again:" << endl;
return 0;
}
}
else
{
++expression;
}
}
list<struct data>::iterator iterator = calculate.l.begin();
while (iterator != calculate.l.end())
{
calculate.P.push(*iterator);
++iterator;
}
calculate.l.clear();
calculate.infixToPostfix();
calculate.solve();
cout << "The result of this expression is: \n" << calculate.R.top() << endl;
}
return 0;
}
Last edited on Dec 11, 2018 at 9:27pm UTC
Dec 12, 2018 at 2:18am UTC
> But after this, the program stops on its own
1 2 3
cout << "Unrecognized symbol encountered : \"" << str[expression] << "\"" << endl;
cout << "Please try again:" << endl;
return 0;
¿why did you put
return 0;
there? ¿what did you expected to happen?
Dec 12, 2018 at 2:47am UTC
even when I take that away it still stops running the program
Dec 12, 2018 at 5:26am UTC
Perhaps if your main wasn't so bloated, you could create a decent program flow.
1 2 3 4 5 6 7 8 9
int main ( ) {
string str;
while ( getline(cin, str, '\n' ) ) {
calculator calculate;
if ( parse(str,calculate) ) {
cout << "The result of this expression is: \n" << evaluate(calculate) << endl;
}
}
}
Where
- parse is basically your
while (expression < str.length()) loop, which returns true if all is well, and returns false at your error condition.
- evaluate is from your list iterator, and ends with a final
return calculate.R.top();
Topic archived. No new replies allowed.