简单的计算器

http://www.zhihu.com/question/28049221

这里有个问题说:

能用c语言编写一个简单的计算器,包含加减乘以及括号之间的优先级关系,这样的编程能力算是什么程度?

我也很好奇,能写出来到底怎么样。我写出的代码到底怎么样。便有了下面的代码。

毕竟是好久没有写这些小程序了。

#include <iostream>
#include <stack>
#include <map>
using namespace std;

//get a number from a string["123nc14"==>123]
bool getNumber(char* input,int& number,int& strMoveOffset)
{
    strMoveOffset = 0;
    while(input[strMoveOffset]>=48
        &&input[strMoveOffset]<58)//this char is a number
    {
        strMoveOffset++;    
    }    
    if(!strMoveOffset)//this char is a operator
    {
        return false;
    }
    //parse the number
    number = atoi(input);
    return true;
};

int main(int argc,char** argv)
{
    //string for input
    char input[256];
    //number stack and operator stack
    stack<int> NumStack;
    stack<char> OperatorStack;
    //hashtable for operators' priority
    map<char,int> operatorPriority;
    operatorPriority['+']=1;
    operatorPriority['-']=1;
    operatorPriority['*']=2;
    operatorPriority['/']=2;
    operatorPriority['(']=3;
    operatorPriority[')']=0;
    operatorPriority['\0']=-1;
    
    std::cin.getline(input,256);
    std::cout<<input<<std::endl;
    char* ptr = input;
    int strOffset = 0;
    int number;
    while(true)
    {
        if(getNumber(ptr,number,strOffset))
        {
            //we got a number
            NumStack.push(number);    
        }
        else
        {
            //we got an operator
            
            char curOp = ptr[0];
            //now for calculating
            
            //if we have operator in the stack and current char own higher priority 
            // than the top operator in the stack
            //and ignore '(' in order to avoid this case[2*(3+4)==>  23  *(+ perform2(3??]
            if(OperatorStack.size()>0&&operatorPriority[OperatorStack.top()]>=
                operatorPriority[curOp]&&OperatorStack.top()!='(')
            {
                while(OperatorStack.size()>0&&operatorPriority[OperatorStack.top()]>=
                operatorPriority[curOp])
                {
                    //perform this calculation
                    int number1,number2;
                    
                    if(OperatorStack.top() == '(')
                    {
                        //ignore this case.just pop it
                    }
                    else 
                    {
                        number2 = NumStack.top();NumStack.pop();
                        number1 = NumStack.top();NumStack.pop();
                        
                        switch(OperatorStack.top())
                        {
                            case '+':
                                NumStack.push(number2+number1);
                            break;
                            case '-':
                                NumStack.push(number1-number2);
                            break;
                            case '*':
                                NumStack.push(number2*number1);
                            break;
                            case '/':
                                NumStack.push(number1/number2);
                            break;
                        }
                    }
                    OperatorStack.pop();//remove this operator
                }
                
                OperatorStack.push(curOp);//add next new operator
            }
            else
            //push it if nothing happended
                OperatorStack.push(ptr[0]);
                
            ptr+=1;
        }
        
        if(ptr[0]=='\0')
        break;
        
        ptr+=strOffset;
    }
    
    //output result
    std::cout<<NumStack.top()<<std::endl;
    //test
    //int k = atoi("12*(");
    //std::cout<<k<<std::endl;
    return 0;
}

 

posted @ 2015-02-09 17:07  kalluwa  阅读(204)  评论(0编辑  收藏  举报