1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
// EX6_10.cpp
// A program to implement a calculator
#include <iostream> // For stream input/output
#include <cstdlib> // For the exit() function
#include <cctype> // For the isdigit() function
using std::cin;
using std::cout;
using std::cerr;
using std::endl;
void eatspaces(char* str); // Function to eliminate blanks
double expr(char* str); // Function evaluating an expression
double term(char* str, int& index); // Function analyzing a term
double number(char* str, int& index); // Function to recognize a number
const int MAX(80); // Maximum expression length,
// including '\0'
int main()
{
char buffer[MAX] = {0}; // Input area for expression to be evaluated
cout << endl
<< "Welcome to your friendly calculator."
<< endl
<< "Enter an expression, or an empty line to quit."
<< endl;
for(;;)
{
cin.getline(buffer, sizeof buffer); // Read an input line
eatspaces(buffer); // Remove blanks from input
if(!buffer[0]) // Empty line ends calculator
return 0;
try
{
cout << "\t= " << expr(buffer) // Output value of expression
<< endl << endl;
}
catch( const char* pEx)
{
cerr << pEx << endl;
cerr << "Ending program." << endl;
return 1;
}
}
}
// Function to eliminate spaces from a string
void eatspaces(char* str)
{
int i(0); // 'Copy to' index to string
int j(0); // 'Copy from' index to string
while((*(str + i) = *(str + j++)) != '\0') // Loop while character
// copied is not \0
if(*(str + i) != ' ') // Increment i as long as
i++; // character is not a space
return;
}
// Function to evaluate an arithmetic expression
double expr(char* str)
{
double value(0.0); // Store result here
int index(0); // Keeps track of current character position
value = term(str, index); // Get first term
for(;;) // Indefinite loop, all exits inside
{
switch(*(str + index++)) // Choose action based on current character
{
case '\0': // We're at the end of the string
return value; // so return what we have got
case '+': // + found so add in the
value += term(str, index); // next term
break;
case '-': // - found so subtract
value -= term(str, index); // the next term
break;
default: // If we reach here the string is junk
char message[38] = "Expression evaluation error. Found: ";
strncat_s(message, str + index - 1, 1); // Append the character
throw message;
break;
}
}
}
// Function to get the value of a term
double term(char* str, int& index)
{
double value(0.0); // Somewhere to accumulate
// the result
value = number(str, index); // Get the first number in the term
// Loop as long as we have a good operator
while(true)
{
if(*(str + index) == '*') // If it's multiply,
value *= number(str, ++index); // multiply by next number
else if(*(str + index) == '/') // If it's divide,
value /= number(str, ++index); // divide by next number
else
break;
}
return value; // We've finished, so return what
// we've got
}
// Function to recognize a number in a string
double number(char* str, int& index)
{
double value(0.0); // Store the resulting value
// There must be at least one digit...
if(!isdigit(*(str + index)))
{ // There's no digits so input is junk...
char message[31] = "Invalid character in number: ";
strncat_s(message, str+index, 1); // Append the character
throw message;
}
while(isdigit(*(str + index))) // Loop accumulating leading digits
value = 10*value + (*(str + index++) - '0');
// Not a digit when we get to here
if(*(str + index) != '.') // so check for decimal point
return value; // and if not, return value
double factor(1.0); // Factor for decimal places
while(isdigit(*(str + (++index)))) // Loop as long as we have digits
{
factor *= 0.1; // Decrease factor by factor of 10
value = value + (*(str + index) - '0')*factor; // Add decimal place
}
return value; // On loop exit we are done
}
|