RPN Calculator с использованием заголовочных файлов для операций калькуляции и стека;вектор, используемый для стека - PullRequest
0 голосов
/ 27 октября 2019

Я пытаюсь создать калькулятор 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

Вотфрагмент того, что у меня есть для заголовочного файла rpn.h.

#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);
        }       
    }
}

Вот мой файл cpp

#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);
    }
}

1 Ответ

0 голосов
/ 27 октября 2019

Ваша ветка else в rpn8::process, вероятно, неверна. if (!at) будет переходить в else-ветку всякий раз, когда вы вводите число (когда st >> values успешно). Но тогда вы не обрабатываете это число, а обрабатываете его как недействительный токен.

Некоторые другие примечания:

  • std::cout<< st.getsize() << " values remain on the stack." << endl; несколько страннопотому что stack8::getsize ничего не возвращает, а выводит значение и выходит из всей программы.
  • at.str(""); не ищет никаких индикаторов, а просто заменяет содержимое потока строки пустой строкой.
...