简单计算器 C++语言实现 支持四则运算、取余、正负数、括号

2021-02-05 10:03:54 浏览数 (1)

参考链接: C 程序,使简单的计算器使用switch ... case进行加,减,乘或除运算

/* 

Simple calculator 

input from cin,output to cout 

简单计算器:支持加减乘除取余、正负数、括号  

主要实现: 

1.两个类Token和Token_stream:将输入表达式分为单词如1.82, ,(,存储在Token类对象中,Token_stream类实现能缓存1个单词的流 

2.三个实现语法的函数expression(),term(),primary():实现表达式计算顺序 

3.计算流程函数calculate():用循环实现任意次数表达式计算,直到出错或正常退出 

The grammar is: 

Statement: 

    Expression 

    Print 

    Quit 

Print: 

    ; 

Quit: 

    q 

Expression 

    Term 

    Expression Term 

    Expression - Term 

Term: 

    primary 

    Term * primary 

    Term / primary 

    Term % primary 

Primary: 

    Num 

    ( Expression ) 

    primary 

    - primary 

Num: 

    floating-point-literal 

*/  

#include <iostream>  

using namespace std;  

class Token;  

class Token_stream;  

void keep_window_open();  

double expression();  

double term();   

double primary();  

void welcome();  

void calculate();  

const char number = '8';  

const char print = ';';  

const char quit = 'e';  

const string prompt = ">";  

const string myresult = "=";   

class Token{  

public:  

    char m_kind;  

    double m_value;  

    Token(char kind = '', double value = 0)  

        :m_kind(kind)  

        ,m_value(value)  

    {}  

};   

class Token_stream{  

public:  

    Token get();  

    void putback(Token t);  

    Token_stream()  

        :m_full(false)  

        ,m_buffer('', 0)  

    {}   

private:  

    bool m_full;  

    Token m_buffer;  

};  

//定义能够缓存1个单词的流ts   

Token_stream ts;  

Token Token_stream::get()  

{  

    //缓冲区有单词,从缓冲区中取单词   

    if(true == m_full){  

        m_full = false;  

        return m_buffer;  

    }  

    //缓冲区没有单词,从输入流中取单词   

    char ch;  

    cin>>ch;  

    switch(ch){  

        case ' ':  

        case '-':  

        case '*':  

        case '/':  

        case '%':  

        case '(':  

        case ')':  

        case print:  

        case quit:  

            return Token(ch);  

        case '.':  

        case '0':case '1':case '2':case '3':case '4':  

        case '5':case '6':case '7':case '8':case '9':  

            {  

                cin.putback(ch);  

                double val;  

                cin>>val;  

                return Token(number, val);  

            }  

        default:  

            {  

                cout<<"err input!"<<endl;  

                keep_window_open();  

            }  

    }  

}  

void Token_stream::putback(Token t)  

{  

    if(true == m_full){  

        cout<<"err: m_buffer is full."<<endl;  

        keep_window_open();  

        return;  

    }  

    m_full = true;  

    m_buffer = t;  

}  

void keep_window_open()  

{  

    char ch;  

    fflush(stdin);  

    cin>>ch;  

    exit(EXIT_FAILURE);  

}  

//处理 - 加、减运算  

double expression()  

{  

    double left = term();  

    Token t = ts.get();  

    while(true){  

        switch(t.m_kind){  

            case ' ':  

                left = term();  

                t = ts.get();  

                break;   

            case '-':  

                left -= term();  

                t = ts.get();  

                break;  

            default:  

                ts.putback(t);  

                return left;  

        }  

    }  

}   

//处理* / % 乘、除、取余运算  

double term()  

{  

    double left = primary();  

    Token t = ts.get();  

    while(true){  

        switch(t.m_kind){  

            case '*':  

                left *= primary();  

                t = ts.get();  

                break;   

            case '/':  

                {  

                    double d = primary();  

                    if(0 == d){  

                        cout<<"divide into zero"<<endl;  

                        keep_window_open();  

                    }  

                    left /= d;  

                    t = ts.get();  

                    break;   

                }  

            case '%':  

                {  

                    double d = primary();  

                    int i1 = int(left);  

                    int i2 = int(d);  

                    if(i1 != left){  

                        cout<<"left operand not int"<<endl;  

                        keep_window_open();  

                    }  

                    if(i2 != d){  

                        cout<<"right operand not int"<<endl;  

                        keep_window_open();  

                    }  

                    if(i2 == 0){  

                        cout<<"% divide into 0"<<endl;  

                    }  

                    left = i1 % i2;  

                    t = ts.get();  

                    break;   

                }  

            default:  

                ts.putback(t);  

                return left;  

        }  

    }  

}   

//处理()- 括号、正、负运算  

double primary()  

{  

    Token t = ts.get();  

    switch(t.m_kind){  

        case number:  

            return t.m_value;  

        case '(':  

            double d = expression();  

            t = ts.get();  

            if(')' != t.m_kind){  

                cout<<"expected ')'"<<endl;  

                keep_window_open();  

            }  

            return d;  

        case '-':  

            return -primary();  

        case ' ':  

            return primary();  

        default:  

            cout<<"expected primary!"<<endl;  

            keep_window_open();  

    }  

}  

void calculate()  

{  

    while(cin){  

        cout<<prompt;  

        Token t = ts.get();  

        while(print == t.m_kind)t = ts.get();  

        if(quit == t.m_kind)return;       

        else  

            ts.putback(t);  

        cout<<myresult<<expression()<<endl;  

    }  

}  

void welcome()  

{  

    cout<<"Welcome to our simple calculator."<<endl  

        <<"-----------------------------"<<endl  

        <<"floating-point numbers"<<endl  

        <<"operator: ' ' '-' '*' '/' '%'"<<endl  

        <<"negative: '-'"<<endl  

        <<"positive: ' '"<<endl  

        <<"end of expression: ';'"<<endl  

        <<"quit: 'e'"<<endl  

        <<"-----------------------------"<<endl;  

}   

int main()  

{  

    welcome();  

    calculate();  

    cout<<"See you."<<endl;  

    keep_window_open();  

    return 0;  

}

0 人点赞