Мне нужно создать калькулятор RPN, который работает с входными файлами. Он использует 4 стандартных арифметических оператора, а также pow и%. Я не уверен, почему следующая программа не работает для последних 4 строк ввода. Я получаю вывод «SYNTAX ERROR» для последних 4 строк. Есть идеи или предложения? Пример входного файла .txt, который я использую:
3 4 5,0 * —
7
4 * 8 30 +
банан
9 10 + 30 —
900 40,65-20 +
45,29,999%
10 Pow 2
И правильный вывод должен быть:
-17
7
ОШИБКА СИНТАКСИСА
ОШИБКА СИНТАКСИСА
-11
9
879,35
21,201
100
#include<iostream>
#include<fstream>
#include<string>
#include<stack>
#include<sstream>
#include<math.h> //pow
#define SPACE(b) if (!(b)) throw "";
using namespace std;
double evalrpn(stack<string> & tkline);
int main(void){
string line;
ifstream inputfile;
string fileloc;
one:cout << "Enter the location of the input file: ";
getline(cin, fileloc);
inputfile.open(fileloc);
while (inputfile.fail())
{
cout << "The file at location " << fileloc << " failed to open." << endl;
goto one;
}
while (getline(inputfile, line)){
stack<string> tkline;
istringstream sstr(line);
string tk;
while (sstr >> tk)
tkline.push(tk);
if (!tkline.empty())
try {
auto z = evalrpn(tkline);
SPACE(tkline.empty());
cout << z << endl;
}
catch (...) { cout << "SYNTAX ERROR" << endl; }
}cin.ignore();
return 0;
}
double evalrpn(stack<string> & tkline){
SPACE(!tkline.empty());
double x, y;
auto tk = tkline.top();
tkline.pop();
auto n = tk.size();
if (n == 1 && string("+-*/%'pow'").find(tk) != string::npos) {
y = evalrpn(tkline);
x = evalrpn(tkline);
if (tk[0] == '+') x += y;
else if (tk[0] == '-') x -= y;
else if (tk[0] == '*') x *= y;
else if (tk[0] == '/') x /= y;
else if (tk[0] == '%') x = fmod(x,y);
else pow(x, y);
}
else {
unsigned i; x = stod(tk, &i);
SPACE(i == n);
}
return x;
}
Ваша программа не обрабатывает случай, когда между токенами нет пробелов, потому что istringstream
не занимается этим делом для вас. Вам придется использовать более интеллектуальный парсер, чем разбивать токены на пробелы.