逆ポーランド記法電卓 C++
#include <stdio.h>
#include <conio.h>
#include <math.h>
#define STACK_SIZE 10
#define NUM_DIGITS 8
typedef enum _OPERATION
{
OPE_PLUS,
OPE_MINUS,
OPE_MULTIPLY,
OPE_DIVIDE,
OPE_INVERSION,
OPE_CLEAR,
OPE_ENTER,
OPE_EXIT
}OPERATION;
class CalcStack
{
private:
double mValues[STACK_SIZE];
int mCount=0;
public:
enum STACK_ERROR
{
ERR_OVERFLOW,
ERR_PARAM,
ERR_EMPTY
};
void Push(double value)
{
if (mCount >= STACK_SIZE)
throw ERR_OVERFLOW;
mValues[ mCount++] = value;
}
double Pop()
{
if (mCount <= 0)
throw ERR_EMPTY;
return mValues[ --mCount];
}
int Count() const
{
return mCount;
}
double GetValue(int n) const
{
if (n < 0 || n >= mCount)
throw ERR_PARAM;
return mValues[n];
}
};
OPERATION Input(CalcStack& rstack)
{
char number[NUM_DIGITS + 1];
int cntnum = 0;
OPERATION ope = OPE_ENTER;
for (;;)
{
int ch = _getche();
if ('0' <= ch && ch <= '9' || ch == '.')
{
if (cntnum < NUM_DIGITS)
{
number[cntnum++] = (char)ch;
number[cntnum] = 0;
}
}
else{
if (ch == '+')
ope = OPE_PLUS;
else if (ch == '-')
ope = OPE_MINUS;
else if (ch == '*')
ope = OPE_MULTIPLY;
else if (ch == '/')
ope = OPE_DIVIDE;
else if (ch == '!')
ope = OPE_INVERSION;
else if (ch == 'c' || ch == 'C')
ope = OPE_CLEAR;
else if (ch == 'q' || ch == 'Q')
ope = OPE_EXIT;
break;
}
}
if (cntnum > 0)
rstack.Push( atof(number));
return ope;
}
void ShowCalculator(const CalcStack& rstack)
{
int i;
printf("\n/// RPN Calculator ///////////////////////////////");
printf("\n/// +:加 -:減 *:乗 /:除 !:符号 c:削除 q:終了 ///\n");
for (i = 0; i < rstack.Count(); i++)
printf("%2d:%f\n", rstack.Count() - i, rstack.GetValue(i));
printf(">");
}
void main(void)
{
CalcStack stack;
for (;;)
{
OPERATION operation;
try{
ShowCalculator(stack);
operation = Input(stack);
if (operation == OPE_INVERSION || operation == OPE_CLEAR){
double n = stack.Pop();
if (operation == OPE_INVERSION)
stack.Push(n * (-1.0));
}
else if (operation == OPE_PLUS || operation == OPE_MINUS
|| operation == OPE_MULTIPLY || operation == OPE_DIVIDE)
{
double n1 = stack.Pop();
double n2 = stack.Pop();
if (operation == OPE_PLUS)
stack.Push( n1 + n2);
else if (operation == OPE_MINUS)
stack.Push( n2 - n1);
else if (operation == OPE_MULTIPLY)
stack.Push( n1 * n2);
else if (operation == OPE_DIVIDE)
{
if (n1 == 0.0)
printf("\nDivide by Zero!\n");
else
stack.Push( n2 / n1);
}
}
else if (operation == OPE_EXIT)
{
break;
}
}
catch (CalcStack::STACK_ERROR err)
{
if (err == CalcStack::ERR_OVERFLOW)
printf("\nOverflow!\n");
else
printf("\nError!\n");
}
}
}