c++实现的一个控制台下的计算器

第一次写博客,心情有点小激动呢大笑。本人小菜,学习完了c++,现在刚开始学习数据结构。前两天用c++实现了一个控制台计算器,想我菜鸟也是费了一番周折。计算器功能:支持整形和浮点型基本运算,支持括号。也支持负数,但是在算式中需要加上括号。

废话 不多说,上代码。大神勿喷!!不足之处,还望众大神多多提点。

创建一个Stack类

#ifndef STACK_H
#define STACK_H
#include <iostream>
using namespace std;
const int maxSize = 20;

template <typename T>
class Stack
{
public:
 T nums[maxSize];
 int count;

public:
 Stack()  //构造函数,并初始化栈
 {
  count = 0;
 }

 void initStack()  //初始化栈函数
 {
  count = 0;
 }

 bool empty()
 {
  if (count == 0)
   return true;

  return false;
 }

 bool full()
 {
  if (count == maxSize)
   return true;

  return false;
 }

 T get_top(T &num)
 {
  if (empty())  //若栈为空报错
  {
   cout << "1underflow!" << endl; 
   return -1;
  }

  else
   num = nums[count - 1];
  return num;
 }

 void push(T num)
 {
  if (full())
  {
   cout << "overflow!" << endl;
  }
  else
  {
   nums[count] = num;
   count++;
  }
 }

 void pop()
 {
  if (empty())
  {
   cout << "2underflow!" << endl;
  }

  else
   count--;
 }
};
#endif


创建计算类

#include <cstring>
#include "Stack.h"

class Cal
{
public :
 Stack<double> numStack;
 Stack<char> charStack;

 void getNum(char *str)
 { 
  int len = strlen(str);
  *(str + len) = '#';  //在字符串尾加上#,作为结束标志

  charStack.push('#'); //压入#用于比较优先级 
  
  char sign = '\0';  //定义一个开关用于检验括号后的数字是否为负数
  while (*str)
  { 
   //遇到字符数字将其转化为数值型
   if (isdigit(*str) || *str == '.')
   {
    double num = 0;
    while (isdigit(*str))
    {
     num = num * 10 + (*(str++) - '0');
    }

    if (*(str) == '.')
    {
     str++;
     double temp = 0.1;
     while (isdigit(*str))
     {
      num = num + (*(str++) - '0') * temp;

      temp /= 10;
     }
    }    
    
    //检查该数字是否是负数
    char beforeOpe;
    charStack.get_top(beforeOpe); 
    if (beforeOpe == '-')
    {
     if (numStack.empty())
     {
      numStack.push(-num);
      charStack.pop();
     }

     else if(sign == '(')  //解决括号里的负数
     {
      numStack.push(-num);
      charStack.pop();
      sign = '\0';
     }

     else
      numStack.push(num);      
    }

    else
    {
     numStack.push(num);
    }    
   }

   else if (*str == '(')   //遇到左括号将其压入运算符栈
   {
    charStack.push(*str);
    str++;

    if (*str == '-')
     sign = '(';
   }

   else if (*str == ')')  //遇到又括号将前面算式弹出计算直到遇到左括号
   {
    char beforeOpe;
    charStack.get_top(beforeOpe);
    while (beforeOpe != '(')
    {
     double leftNum, rightNum;
     numStack.get_top(rightNum);
     numStack.pop();
     numStack.get_top(leftNum);
     numStack.pop();
     cal(leftNum, rightNum, beforeOpe);
     charStack.pop();
     charStack.get_top(beforeOpe);
    }

    charStack.pop();  //弹出左括号
    str++;
   }

   else
   {
    char beforeOpe;
    charStack.get_top(beforeOpe);
    if (getPri(*str) > getPri(beforeOpe))  //如果该优先级大于前面的压栈
    {
     charStack.push(*str);
     str++;
    }
      
    else if ((getPri(*str) == 0) && getPri(beforeOpe) == 0)  //当前后均为#时跳出循环,运算结束
    {
     break;
    }

    else  //如果小于前面的,弹出运算
    { 
     double leftNum, rightNum;
     numStack.get_top(rightNum);
     numStack.pop();
     numStack.get_top(leftNum);
     numStack.pop();
     cal(leftNum, rightNum, beforeOpe);
     charStack.pop();    
    }
   }
  } 
 }

 void cal(double leftNum, double rightNum, char ch)  //运算函数
 {
  switch (ch)
  {
  case '+':
   numStack.push(leftNum + rightNum);
   break;

  case '-':
   numStack.push(leftNum - rightNum);
   break;

  case '*':
   numStack.push(leftNum * rightNum);
   break;

  case '/':
   if (rightNum)
    numStack.push(leftNum / rightNum);

   else
    cout << "除数不能为0!" << endl;
   break;
  default:
   break;
  }
 }

 int getPri(char ch)  //获取运算符优先级
 {
  switch (ch)
  {
  case'#':
   return 0;

  case '+':
  case '-':
   return 1;

  case '*':
  case '/':
   return 2;

  case '(':
   return -1;
  } 
 }

 void getResult()
 {
  double res;
  if (numStack.empty())
  {
   cout << "请输入算式!" << endl;
  }

  else
  {
   numStack.get_top(res);
   cout << "relult=" << res << endl << endl;
  }
 }
};

main 函数

#include "Cal.h"

int main()
{
 Cal cal;
 char str[30];
 
 while (1)
 {
  cout << "请输入算式:" << endl;
  cin >> str;
  cal.getNum(str);
  cal.getResult();

  cal.numStack.initStack(); //清空数字栈,开始下次计算
  cal.charStack.initStack(); //清空运算符栈
 }
 return 0;
}

好吧,以前没有弄过。没有搞出行号 =_=||。凑合看吧。。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值