├── .gitignore ├── makefile ├── scientific.h ├── calculator.h ├── Calculator.cbp ├── main.cpp ├── scientific.cpp ├── calculator.cpp └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.docx 2 | *.mp4 3 | *.o 4 | main 5 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | main: main.o calculator.o scientific.o 2 | g++ -o main main.o calculator.o scientific.o 3 | 4 | main.o: main.cpp calculator.h scientific.h 5 | g++ -c main.cpp 6 | 7 | calculator.o: calculator.cpp calculator.h 8 | g++ -c calculator.cpp 9 | 10 | scientific.o: scientific.cpp scientific.h 11 | g++ -c scientific.cpp 12 | -------------------------------------------------------------------------------- /scientific.h: -------------------------------------------------------------------------------- 1 | #ifndef SCIENTIFIC_H 2 | #define SCIENTIFIC_H 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | #include "calculator.h" 9 | 10 | class Scientific : public Calculator 11 | { 12 | public: 13 | Scientific(); /// Constructor 14 | virtual ~Scientific() = default; /// Virtual destructor to prevent delete errors 15 | virtual void welcome() const override; /// Options message 16 | virtual void parseOperation(const std::string& input) override; /// Parse operation input and call correct member func 17 | /// Extra operations not in simple calc 18 | void sin(); 19 | void cos(); 20 | void tan(); 21 | void ln(); 22 | void log(); 23 | void abs(); 24 | void pow(); 25 | }; 26 | 27 | #endif // SCIENTIFIC_H 28 | -------------------------------------------------------------------------------- /calculator.h: -------------------------------------------------------------------------------- 1 | #ifndef CALCULATOR_H 2 | #define CALCULATOR_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class Calculator 9 | { 10 | public: 11 | Calculator(); /// Constructor 12 | virtual ~Calculator() = default; /// Virtual destructor to prevent delete errors 13 | void add(); /// Functions to get user input and do operation 14 | void subtract(); 15 | void multiply(); 16 | void divide(); 17 | void square(); 18 | void sqrt(); 19 | void setMem(); /// Functions to get and set mem 20 | void printMem() const; 21 | 22 | /// Parse input subs in number value when strings result or mem are entered 23 | double parseInput(const std::string&) const; 24 | 25 | /// provides data on user options, will be overloaded 26 | virtual void welcome() const; 27 | 28 | /// parse input and decide which member func to call 29 | virtual void parseOperation(const std::string&); 30 | 31 | /// protected so derived class can access. 32 | protected: 33 | double result; /// data member to store result 34 | double mem; /// data member to store mem 35 | }; 36 | 37 | #endif // CALCULATOR_H 38 | -------------------------------------------------------------------------------- /Calculator.cbp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 47 | 48 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "calculator.h" 4 | #include "scientific.h" 5 | 6 | using namespace std; 7 | 8 | int main() 9 | { 10 | 11 | /// Initialize simple calc and scientific calc objects 12 | Calculator calc; 13 | Scientific sci; 14 | 15 | /// Assign calculator pointer to the simple calc object 16 | /// This will be used later for polymorphism 17 | Calculator* calcPtr = &calc; 18 | 19 | /// Switch to flip scientific calc on and off 20 | bool sciActive = false; 21 | 22 | cout << "Welcome to my Calculator App\n\n" 23 | << "This calculator has 2 modes, normal and scientific.\n" 24 | << "You can change it using the 'change' keyword.\n\n" 25 | << "This app has 2 other special keywords, result and mem.\n" 26 | << "result stores the result of the previous calculation.\n" 27 | << "mem allows you to store and access a number.\n" 28 | << "Both can be used instead of numbers during calculations.\n" 29 | << "They are both local to the mode you are using.\n"; 30 | 31 | /// Welcome message for simple calc 32 | calcPtr->welcome(); 33 | 34 | /// Set precision for all uses of cout 35 | /// Shows up to 15 places 36 | cout << setprecision(15); 37 | 38 | /// Take in input and loop 39 | string input = ""; 40 | while (cin >> input && input != "exit") 41 | { 42 | /// Input to switch mode 43 | if (input == "change") 44 | { 45 | if (sciActive) 46 | { 47 | /// Set pointer to the simple calc object 48 | calcPtr = &calc; 49 | sciActive = false; 50 | cout << "\nSimple Calculator Activated"; 51 | } else /// sciActive is false 52 | { 53 | /// Set pointer to scientific calc object 54 | calcPtr = &sci; 55 | sciActive = true; 56 | cout << "\nScientific Calculator Activated"; 57 | } 58 | } 59 | /// Call virtual functions from base class pointer to get polymorphic 60 | /// Executes function based on type of object 61 | calcPtr->parseOperation(input); 62 | calcPtr->welcome(); 63 | } 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /scientific.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "scientific.h" 3 | 4 | /// Constructor 5 | Scientific::Scientific() : Calculator() {} 6 | 7 | /// Overrided welcome message to show scientific options 8 | void Scientific::welcome() const 9 | { 10 | std::cout << "\n\nEnter one of:\n" 11 | << "+, -, /, *, sqrt, square, change, setmem, printmem, sin, cos, log, tan, ln, abs, pow\n" 12 | << "or exit\n"; 13 | } 14 | 15 | /// Overridded parse operation to call correct member function 16 | void Scientific::parseOperation(const std::string& input) 17 | { 18 | /// Reuse code for all simple calc inputs 19 | /// If no simple calc match found it will continue below 20 | Calculator::parseOperation(input); 21 | 22 | if (input == "sin") 23 | { 24 | sin(); 25 | } 26 | else if (input == "cos") 27 | { 28 | cos(); 29 | } 30 | else if (input == "tan") 31 | { 32 | cos(); 33 | } 34 | else if (input == "ln") 35 | { 36 | ln(); 37 | } 38 | else if (input == "log") 39 | { 40 | log(); 41 | } 42 | else if (input == "abs") 43 | { 44 | abs(); 45 | } 46 | else if (input == "pow") 47 | { 48 | pow(); 49 | } 50 | } 51 | void Scientific::sin() 52 | { 53 | std::string a; 54 | std::cout << "Enter a number: "; 55 | std::cin >> a; 56 | result = std::sin(parseInput(a)); 57 | std::cout << "The result is " << result; 58 | } 59 | void Scientific::cos() 60 | { 61 | std::string a; 62 | std::cout << "Enter a number: "; 63 | std::cin >> a; 64 | result = std::cos(parseInput(a)); 65 | std::cout << "The result is " << result; 66 | } 67 | void Scientific::tan() 68 | { 69 | std::string a; 70 | std::cout << "Enter a number: "; 71 | std::cin >> a; 72 | result = std::tan(parseInput(a)); 73 | std::cout << "The result is " << result; 74 | } 75 | void Scientific::ln() 76 | { 77 | std::string a; 78 | std::cout << "Enter a number: "; 79 | std::cin >> a; 80 | result = std::log(parseInput(a)); 81 | std::cout << "The result is " << result; 82 | } 83 | void Scientific::log() 84 | { 85 | std::string a, b; 86 | std::cout << "Enter the base: "; 87 | std::cin >> a; 88 | std::cout << "Enter a number: "; 89 | std::cin >> b; 90 | result = std::log(parseInput(b))/std::log(parseInput(a)); 91 | std::cout << "The result is " << result; 92 | } 93 | void Scientific::abs() 94 | { 95 | std::string a; 96 | std::cout << "Enter a number: "; 97 | std::cin >> a; 98 | result = std::abs(parseInput(a)); 99 | std::cout << "The result is " << result; 100 | } 101 | void Scientific::pow() 102 | { 103 | std::string a, b; 104 | std::cout << "Enter the base: "; 105 | std::cin >> a; 106 | std::cout << "Enter the exponent: "; 107 | std::cin >> b; 108 | result = std::pow(parseInput(a), parseInput(b)); 109 | std::cout << "The result is " << result; 110 | } 111 | -------------------------------------------------------------------------------- /calculator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "calculator.h" 3 | 4 | /// Constructor 5 | /// Initilize data members to 0 doubles 6 | Calculator::Calculator() : result(0.0), mem(0.0) {} 7 | 8 | void Calculator::add() 9 | { 10 | std::string a, b; 11 | std::cout << "Enter the first number: "; 12 | std::cin >> a; 13 | std::cout << "Enter the second number: "; 14 | std::cin >> b; 15 | result = parseInput(a) + parseInput(b); 16 | std::cout << "The result is " << result; 17 | } 18 | void Calculator::subtract() 19 | { 20 | std::string a, b; 21 | std::cout << "Enter the first number: "; 22 | std::cin >> a; 23 | std::cout << "Enter the second number: "; 24 | std::cin >> b; 25 | result = parseInput(a) - parseInput(b); 26 | std::cout << "The result is " << result; 27 | } 28 | void Calculator::multiply() 29 | { 30 | std::string a, b; 31 | std::cout << "Enter the first number: "; 32 | std::cin >> a; 33 | std::cout << "Enter the second number: "; 34 | std::cin >> b; 35 | result = parseInput(a) * parseInput(b); 36 | std::cout << "The result is " << result; 37 | } 38 | void Calculator::divide() 39 | { 40 | std::string a, b; 41 | std::cout << "Enter the first number: "; 42 | std::cin >> a; 43 | std::cout << "Enter the second number: "; 44 | std::cin >> b; 45 | result = parseInput(a) / parseInput(b); 46 | std::cout << "The result is " << result; 47 | } 48 | void Calculator::square() 49 | { 50 | std::string a; 51 | std::cout << "Enter a number: "; 52 | std::cin >> a; 53 | double parsedA = parseInput(a); 54 | result = parsedA * parsedA; 55 | std::cout << "The result is " << result; 56 | } 57 | void Calculator::sqrt() 58 | { 59 | std::string a; 60 | std::cout << "Enter a number: "; 61 | std::cin >> a; 62 | result = std::sqrt(parseInput(a)); 63 | std::cout << "The result is " << result; 64 | } 65 | void Calculator::setMem() 66 | { 67 | std::string a; 68 | std::cout << "Enter a number: "; 69 | std::cin >> a; 70 | mem = parseInput(a); 71 | std::cout << "The mem is " << mem; 72 | } 73 | void Calculator::printMem() const 74 | { 75 | std::cout << "The mem is " << mem; 76 | } 77 | /// subs in number value when strings result or mem are entered 78 | double Calculator::parseInput(const std::string& input) const 79 | { 80 | if (input == "result") 81 | { 82 | return result; 83 | } 84 | else if (input == "mem") 85 | { 86 | return mem; 87 | } 88 | else 89 | { 90 | return std::stod(input); 91 | } 92 | } 93 | void Calculator::welcome() const 94 | { 95 | std::cout << "\n\nEnter an operation (+, -, /, *, sqrt, square, change, setmem, printmem) or exit\n"; 96 | } 97 | /// parse input and decide which member func to call 98 | void Calculator::parseOperation(const std::string& input) 99 | { 100 | if (input == "+" || input == "add" || input == "addition" || input == "sum") 101 | { 102 | add(); 103 | } 104 | else if (input == "-" || input == "sub" || input == "subtraction" || input == "minus") 105 | { 106 | subtract(); 107 | } 108 | else if (input == "/" || input == "divide" || input == "div") 109 | { 110 | divide(); 111 | } 112 | else if (input == "*" || input == "mul" || input == "multiply" || input == "times") 113 | { 114 | multiply(); 115 | } 116 | else if (input == "sqrt") 117 | { 118 | sqrt(); 119 | } 120 | else if (input == "square") 121 | { 122 | square(); 123 | } 124 | else if (input == "setmem") 125 | { 126 | setMem(); 127 | } 128 | else if (input == "printmem") 129 | { 130 | printMem(); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # C++ Command Line Calculator 2 | 3 | This is an extremely simple calculator I made while learning C++. 4 | 5 | Download the repo, compile and run it: 6 | ``` 7 | $git clone https://github.com/christopher-siewert/cpp-calculator.git 8 | $cd cpp-calculator 9 | $make 10 | ``` 11 | 12 | For Windows users, I included my Code::Blocks project file, `Calculator.cbp`. 13 | Open this with the [Code::Blocks](http://www.codeblocks.org/) IDE. 14 | 15 | It has two modes, regular and scientific, that a user can switch between. 16 | 17 | ### Overview 18 | 19 | The program has 2 classes. A simple calculator class called Calculator, and a class that inherits Calculator called Scientific. 20 | 21 | Some of the member functions of Calculator are virtual and are overridden in the Scientific class. 22 | 23 | The program polymorphically calls the appropriate member functions depending on the current mode (scientific vs simple). 24 | 25 | The program flow is: 26 | 1. Prompt user for the desired operation (polymorphically determine the message based on the current mode; show more options while in scientific mode) 27 | 2. Get additional data from the user (if doing addition, get 2 numbers) 28 | 3. Perform calculation, print to screen 29 | 4. Repeat from (1) 30 | 31 | #### Calculator Class 32 | 33 | This is the base class for the calculator program. It has data members and member functions that will display messages to the screen, prompt for user input, and perform calculations. 34 | 35 | Specifically, Calculator has 2 protected data members, `result` and `mem`. `result` stores the result of the last computation. `mem` is used by the user to store a number in memory and access it later for further computation. They are both doubles, and they are initialized to 0 in the constructor. 36 | 37 | Public member functions `add`, `subtract`, `multiply`, `divide`, `square`, and `sqrt` perform all the calculations. They prompt the user for either 1 or 2 numbers depending on the function, perform the required calculation, store this in the protected variable result, and print out the result to the screen. 38 | 39 | Calculator has 2 public member functions in order to use `mem`, a get and a set. 40 | 41 | Then some helper member functions will be needed. 42 | `welcome()` will print out the available options that can be entered. This is virtual so the derived class can output its own options. 43 | 44 | `parseOperation()` takes in the user input string and calls the appropriate member function. This is to enable the user entering "+" or "log" and having the correct function called. This is also virtual so it can be overridden for the extra functions in the scientific calc. 45 | 46 | `parseInput()` is used for the extra `result`/`mem` feature. I wanted the user to be able to type the words result and mem as if they are numbers. `parseInput()` looks for those strings and gets the values from memory to be used in any calculations. 47 | 48 | As this class contains virtual functions, a virtual destructor will be included. 49 | 50 | #### Scientific Class 51 | 52 | Scientific inherits from the base class calculator. It calls the Calculator constructor to initialize `result` and `mem`. 53 | It has many additional operation functions. `sin`, `cos`, `tan`, `ln`, `log`, `abs`, and `pow` all prompt the user for input, perform a calculation, save it in result, and print that result. 54 | 55 | It overrides the 2 virtual functions of class Calculator. `welcome()` is overridden to show all the options for the scientific calculator, and `parseOperation()` is overridden to access the additional calculation functions. 56 | 57 | A virtual destructor is also included. 58 | 59 | #### Main 60 | 61 | The class set up allows the program to polymorphically call object methods depending on the type of the object. The main program will be one user entry loop. In the loop, a base class Calculator pointer (`calcPtr`) pointed at a Calculator object is used to call the Calculator member functions. 62 | 63 | The switch to scientific mode will be made by pointing this Calculator class pointer at a derived Scientific class object. Now the program dynamically calls different member functions based on the state. 64 | 65 | This simplifies the main code as the statement `calcPtr->welcome()` will automatically call the right welcome function, detailing out the proper options for the current mode. 66 | 67 | #### Nifty Features 68 | 69 | 1. Users are able to enter a range of inputs that correspond to each operation. For example: “+”, “add”, “addition”, “sum” all trigger the addition operation. 70 | 2. This calculator has a memory feature. The result of a previous calculation is always stored and can be accessed using the keyword `result`. This keyword can be used as a number. Thus, the user could enter: `sub` to choose the subtraction operation then type in `result` and `1` to take one away from the previous result. The `mem` keyword allows a user to store a number for later use. This is highly useful when doing long calculations. An important result can be stored into `mem`, then accessed later by using `mem` as an entry in your calculations. 71 | --------------------------------------------------------------------------------