C++ RPN计算器使用头文件进行计算操作和堆栈;用于堆栈的向量

C++ RPN计算器使用头文件进行计算操作和堆栈;用于堆栈的向量,c++,class,stack,header-files,rpn,C++,Class,Stack,Header Files,Rpn,我正在尝试创建一个rpn计算器,但必须使用头文件,其中包含计算器函数和堆栈的类声明和定义。我决定为堆栈使用向量,这是我在stack.h文件中创建的。每当我测试程序时,当输入一个不是给定运算符的令牌时,它总是给出我的无效令牌错误。我尝试将它设置到它处理rpn中的值的向量的位置,我尝试为向量创建一个函数以在堆栈头文件中返回向量,以便在rpn头文件中实例化并调用它。出于某种原因,所有这些对我都不起作用。感谢您的帮助 以下是我收到的结果: Please enter numbers and operato

我正在尝试创建一个rpn计算器,但必须使用头文件,其中包含计算器函数和堆栈的类声明和定义。我决定为堆栈使用向量,这是我在stack.h文件中创建的。每当我测试程序时,当输入一个不是给定运算符的令牌时,它总是给出我的无效令牌错误。我尝试将它设置到它处理rpn中的值的向量的位置,我尝试为向量创建一个函数以在堆栈头文件中返回向量,以便在rpn头文件中实例化并调用它。出于某种原因,所有这些对我都不起作用。感谢您的帮助

以下是我收到的结果:

Please enter numbers and operators:
1 2 + =
Invalid token entered.
这是我的堆栈头文件,名为stack8.h

#ifndef STACK8
#define STACK8

#include <iostream>
#include <vector>

using namespace std;

class stack8 {

    std::vector<double> rpn_stack;
    public:
        stack8();
        void push(double vals);
        double pop();
        void dump_op();
        int getsize();
        int i;
        string message;

};

stack8::stack8() {
    int values = 0;
}

void stack8::push(double vals) {
    rpn_stack.push_back(vals);  //pushing any double values found into the stack
    return; 
}
double stack8::pop() {
    double nums; //declaration for operands
    if (rpn_stack.size() <= 0) {  //checking for stack underflow
        std::cerr << "Stack underflow." << endl;
        //use_info.usage_info(message);
        exit(2);
    }
    else {
        nums = rpn_stack.back(); //if no stack underflow, values are user's input
        rpn_stack.pop_back();     //will pop the values at the top of the stack until the end based on user's input
        return nums;              //returning the result of values after popping
    }
}
int stack8::getsize() {
    std::cout<< rpn_stack.size() << " values remain on the stack." << endl; //number of vals in stack
    exit(3);
}

void stack8::dump_op() {
    for (i = 0; i < rpn_stack.size(); ++i) {  //iterating through stack to print values for dump operation
            cout << rpn_stack.at(i) << " ";
        }
}

#endif
\ifndef STACK8
#定义堆栈8
#包括
#包括
使用名称空间std;
第8类{
std::向量rpn_堆栈;
公众:
stack8();
无效推送(双VAL);
双pop();
无效转储_op();
int getsize();
int i;
字符串消息;
};
stack8::stack8(){
int值=0;
}
空堆栈8::推送(双VAL){
rpn_stack.push_back(VAL);//将找到的任何双精度值推入堆栈
返回;
}
双堆栈8::pop(){
double nums;//操作数的声明

if(rpn_stack.size()您在
rpn8::process
中的else分支可能是错误的。
if(!at)
将在您输入数字时转到else分支(当
st>>values
成功)。但是您不处理此数字,而是将其作为无效令牌处理

一些其他注释:


  • std::coutDeclaring
    int values=0;
    在构造函数内部并没有完成任何有用的事情。您似乎没有在
    处处理
    ,也没有正确地迭代
    标记
    。啊,好吧,所以我需要重新思考我是如何处理输入的。我在过去的一个rpn计算程序中使用了这个方法,它起了作用,所以我应该可以在这里使用。另外,可能是因为我正在使用类,而以前的一个没有使用类。我会再试一次。对于如何正确处理作为用户输入的字符串,您有什么建议吗?
    
    #ifndef RPN8
    #define RPN8
    
    #include <iostream>
    #include <string>
    #include <vector>
    #include <cmath>
    #include <sstream>
    using namespace std;
    
    #include "stack8.h"
    stack8 st;    //calling a stack class object to use for the calculator operations
    
    class rpn8 {
        public:
            rpn8();
            double process();
            int getstacksize();
            double values;                 //declaration to use for our calculator operand values
            double tempo;                  //declaration to be used for temporary calc values for certain pop operations
            double r1, r2;                 //same as above, for use with certain pop operations
            string tokens;
            stringstream at;
        private:
            double result;
    
    };
    
    rpn8::rpn8() {
        result = 0;
    }
    
    double rpn8::process() {
    
        cout << "Please enter numbers and operators: " << endl;
        while (std::cin >> tokens) {
                    //asking for user input for calculator operations
            at.str("");         //Looking for "" indicators
            at.clear();         //Removing the "" tokens
            at.str(tokens);     //Setting stringstream to user input entered
            at >> values;
    
            if (!at) {
                if (tokens.compare("+") == 0) {     //finding + in the input and popping two operands for addition
    
                st.push(st.pop() + st.pop());
                }
                else if (tokens.compare("-") == 0){ //finding - in the input and popping two operands for subtraction
                tempo = st.pop();       //using temporary value for subtracting operators
                st.push(st.pop() - tempo);
                }
                else if (tokens.compare("*") == 0) //finding * in the input and popping two operands for multiplication
                {
                    st.push(st.pop() * st.pop());
                } 
                else if (tokens.compare("/")== 0) //finding / in the input and popping two operands for division
                {
                    tempo = st.pop();
    
                    if (tempo == 0) {  //if temp value = 0, division is undefined.  
    
                    std::cerr<< "This results in division by 0, which is undefined.";
                    exit(2);
                    }
                    st.push(st.pop() / tempo); //otherwise, carry out division from pop
                }
                else if (tokens.compare("'") == 0)
                {
                    st.push(1.0 / st.pop());
                }
                else if (tokens.compare("~")== 0) //finding ~ to reverse sign of operand
                {
                    st.push(-st.pop()); 
                }
                else if (tokens.compare("**") == 0) //finding ** for power function
                {
                    tempo = st.pop();
                    st.push(pow(st.pop(), tempo));
                }
                else if (tokens.compare("=") == 0) //time to print the final answer with the equal sign
                {
                   std::cout<< "Result = "<< st.pop() << endl;  //printing results
                   std::cout<< st.getsize() << " values remain on the stack." << endl; //# of vals in stack
                exit(3);
                }
                else if (tokens.compare("dump") == 0) {      //if dump is an operator entered
                  st.dump_op();
                  cout << endl;
                  exit(4);
                }
                else {  //pushing values
                    st.push(values);
                }
            }
            else {   //statement for if any invalid tokens are entered
                std::cerr << "Invalid token entered." << endl;  //error message printed before usage info and termination of program
                //help.usage_info(helps);
                exit(7);
            }       
        }
    }
    
    #include <iostream>
    #include <string>
    
    //adding a call for the rpn8.h header file
    #include "rpn8.h"
    
    int main (int argc, char* argv[]) {
    
        string help_info = "--help";  //string declaration for --help command-line arg
        string begin_prog = "-rpn";    //string declaration for -rpn command-line arg
        string usage_inf;              //string declaration to be used for argument when calling usage info function
        rpn8 calc;                      //instantiation of the rpn8 class
    
    
    
        if (argc == 1) {
            cerr << "Not enough arguments.";
            //help message...
        }
        else if (argc == 2 && (argv[1] == help_info)) { //if command-line arg is --help
            //usage_message(usage_inf);  //printing usage info
        }
        else if (argc == 2 && (argv[1] == begin_prog)) {  //if command-line arg is -rpn, starting calculator operations
    
            calc.process(); //calling the process function from rpn8 using call
        }
        else {
            cerr << "Too many command-line arguments or invalid arguments." << endl; //
            //usage_message(help_usage);
            exit(5);
        }
    }