how to make the calculator program loop after an unrecognized symbol is inputted

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
> 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?
even when I take that away it still stops running the program
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.