Back to Code List
c++

Reverse Polish Notation (RPN) Calculator

This is a simple implementation of a console RPN calculator. It only supports the following operators: * / + -. It also shows a good example of a simple stack.

   Calc.cpp

#include <vector>
#include <iostream>
#include <string>
#include <sstream>

class Calc
{
public:
	void getInput()
	{
		std::string input = "";
		printMenu();
		while (true)
		{
			std::cin >> input;
			if (checkForDouble(input))
				stack.push_back(stringToDouble(input));
			else if (input == "*" || input == "/" || input == "+" || input == "-")
			{
				currOperator = input;
				double result = apply();
				std::cout << "Output:  " << result << std::endl;
			}
			else if (input == "print")
				printStack();
			else if (input == "exit")
				throw std::runtime_error("Thank you for using this program.");
			else if (input == "clear")
				stack.clear();
			else
				throw std::runtime_error("Invalid input entered.");
		}
	};
private:
    std::vector<double> stack;
	std::string currOperator;
	void printMenu()
	{
		std::cout << "--------------------------------------------------------------" << std::endl;
		std::cout << "RPN calculator" << std::endl;
		std::cout << "--------------------------------------------------------------" << std::endl;
		std::cout << "Input your commands. Numbers followed by operators." << std::endl;
		std::cout << "The following are supported: * / + -" << std::endl;
		std::cout << "Enter \"print\" at any point to show the current stack." << std::endl;
		std::cout << "Enter \"clear\" at any point to reset all values on the stack." << std::endl;
		std::cout << "Enter \"exit\" at any point to quit the program." << std::endl;
		std::cout << "--------------------------------------------------------------" << std::endl;
	}
    bool checkForDouble(std::string const& s)
	{
		std::istringstream ss(s);
		double d;
		return (ss >> d) && (ss >> std::ws).eof();
	}
	double stringToDouble(std::string const& s)
	{
		std::istringstream ss(s);
		double d = 0.0;
		ss >> d;
		return d;
	}
	
	double apply()
    {
        if(stack.size() < 2) throw std::runtime_error("Not enough arguments.");

        auto a = stack.back();
        stack.pop_back();

        auto b = stack.back();
        stack.pop_back();

		double result = doOperation(b,a);
        stack.push_back(result);

		currOperator = "";
		return result;
    };
	double doOperation(double b, double a)
	{
		if (currOperator == "*") return a*b;
		if (currOperator == "/")
		{
			if (a == 0) throw std::runtime_error("Divide by zero error.");
			return b/a;
		}
		if (currOperator == "+") return b+a;
		if (currOperator == "-") return b-a;
		return 0.0;
	}
	void printStack() {
		for(int i=0; i<stack.size(); ++i)
		{
			std::cout << stack[i] << " ";
		}
		std::cout << std::endl;
	}
};    

   Main.cpp

#include "Calc.cpp"

int main() {
	Calc c;
	try
	{
		c.getInput();
	}
	catch (std::exception e)
	{
		std::cout << e.what() << std::endl;
	}


	return 0;
}