# Calculator with single line input - follow-up

Part 2 of this question. I've rewritten most parts of the code, for the better I hope. The code now has some more logic and less readability.

Functions included in the calculator:

User input 2+2 Program output 4

• Subtraction
User input 2-2 Program output 0

• Multiplication
User input 2*2 Program output 4

• Division
User input 2/2 Program output 1

• Exponentiation
User input 2^2 Program output 4

#include <iostream>
#include <string>
#include <sstream>
#include <Windows.h>
#include <cmath>

class Math_Functions
{
public:
double subtraction(double, double);
double multiplication(double, double);
void division(double, double);
void exponentiation(double, double);
} math;

class Results_Handler
{
public:
void division(std::string);
void exponentiation(std::string);
} res_handler;

//This function I found somewhere in the deep internet
class Miscellaneous
{
public:
void Pause()
{
std::cout << std::endl << "Press any key to continue . . . ";
std::cin.sync();
std::cin.ignore();
}
void ClearScreen()
{
HANDLE                     hStdOut;
CONSOLE_SCREEN_BUFFER_INFO csbi;
DWORD                      count;
DWORD                      cellCount;
COORD                      homeCoords = { 0, 0 };

hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hStdOut == INVALID_HANDLE_VALUE) return;

/* Get the number of cells in the current buffer */
if (!GetConsoleScreenBufferInfo(hStdOut, &csbi)) return;
cellCount = csbi.dwSize.X *csbi.dwSize.Y;

/* Fill the entire buffer with spaces */
if (!FillConsoleOutputCharacter(
hStdOut,
(TCHAR) ' ',
cellCount,
homeCoords,
&count
)) return;

/* Fill the entire buffer with the current colors and attributes */
if (!FillConsoleOutputAttribute(
hStdOut,
csbi.wAttributes,
cellCount,
homeCoords,
&count
)) return;

/* Move the cursor home */
SetConsoleCursorPosition(hStdOut, homeCoords);
}
} misc;

//Handle the result from division and cout correspondingly
void Results_Handler::division(std::string inPut)
{
if (inPut != "Error")
{
std::cout << inPut;
}
else
{
std::cout << "Come on, you know you can't divide by 0...";
}
}

//Handle the result from the exponentiation and cout correspondingly
void Results_Handler::exponentiation(std::string inPut)
{
if (inPut != "Error")
{
std::cout << inPut;
}
else
{
std::cout << "You can't exponentiate by negative numbers.";
}
}

{
return a + b;
}

double Math_Functions::subtraction(double a, double b)
{
return a - b;
}

double Math_Functions::multiplication(double a, double b)
{
return a * b;
}

void Math_Functions::division(double a, double b)
{
//Dividing by 0 = universe explodes
if (b == 0)
{
res_handler.division("Error");
}
else
{
double c = a / b;
std::stringstream result;
result << c;
res_handler.division(result.str());
}
}

void Math_Functions::exponentiation(double a, double b)
{
//If the number you're exponentiating with is 0 the result is always 1
if (b == 0)
{
res_handler.exponentiation("1");
}
//If you're exponentiating with 1 the result is the same number
else if (b == 1)
{
std::stringstream res;
res << a;
res_handler.exponentiation(res.str());
}
else
{
std::stringstream res;
res << pow(a, b);
res_handler.exponentiation(res.str());
}
}

int main()
{
//Declare variables
double a, b;
char function;
std::string line;

while (true)
{
misc.ClearScreen();
std::getline(std::cin, line);

//Check if the input is empty and ignore
if (line.empty())
{
continue;
}
//Check if the input is either 'q' or 'Q' and break loop
else if (line == 'q' || line == 'Q')
{
break;
}
//Else if everything is OK extract data
else
{
std::istringstream inStream(line);
inStream >> a;
inStream >> function;
inStream >> b;

//Check for bad input and print error
if (!inStream || function != '+' && function != '-' && function != '*' &&     function != '/' && function != '^')
{
std::cerr << "\"" << line << "\" is invalid input";
}
}

//Check what the user wants to do
switch (function)
{
case '+': std::cout << math.addition(a, b); break;
case '-': std::cout << math.subtraction(a, b); break;
case '*': std::cout << math.multiplication(a, b); break;
case '/': math.division(a, b); break;
case '^': math.exponentiation(a, b); break;
}
misc.Pause();
}
return 0;
}

• The request for a library is not on-topic here, nor is it anywhere on SE. You may just have to search for something yourself and try to implement it here. Jan 20, 2015 at 14:33

### The singleton pattern:

Your classes Math_Functions, Results_Handler and Miscellaneous seem like an attempt at the singleton pattern (see 1 and 2). Your approach of declaring a global instance of each class is also valid, but has a few drawback and is not very conventional.

Since your classes hold no member data and the class is really just serving as a name space for the functions, I would use an actual namespace instead and don't even bother with a full-blown singleton implementation in this case. Example:

namespace math
{
double subtraction(double, double);
double multiplication(double, double);
void division(double, double);
void exponentiation(double, double);
} // namespace


Then to access each function you now have to use the :: (namespace resolution) operator: math::addition(a, b);

### Miscellaneous tips:

• Keep parameter names in function prototypes. This adds to the code documentation.

• Be consistent with your naming convention. You have both PascalCase and camelCase names for functions/methods. Choose one and use it consistently.

• Functions from <cmath>, such as pow(), should be accessed using the fully qualified name with the std:: prefix. I.e.: std::pow().

• Consider splitting your project in a few separate source files. There is quite a bit of code here already to be kept all in the same source file. You should ideally place each class in its own .cpp/.h pair.

• Returning zero at the end of main is optional. If you don't do it explicitly, the compiler will default to a return 0.

• I really want to separate the code in different files, but the problem is I don't know how (yet). I can include other .cpp files in the main, but this way it doesn't make much sense to me. Thanks for the guidelines :) Jan 20, 2015 at 17:52
• @skorpi7478, Well, take a look at how to do that in your IDE/compiler. You will then have the class implementation in a .CPP file and the declaration in a header file (.H); Then you include the .H in your other sources files, such as in main.cpp. Jan 20, 2015 at 18:01