所以,我有以下(kludgy!)代码用于后缀表达式转换器和计算器(正如我在上一篇文章中提到的那样:Simple numerical expression solver,感谢所有人!):
#include <iostream>
#include <string>
#include <stack>
using namespace std;
int main()
{
stack<char> operators;
stack<char> output;
stack<char> temp;
stack<char> answer;
string command;
cout << "=>";
cin >> command;
// "Shunting Yard" algorithm
// source: http://en.wikipedia.org/wiki/Shunting-yard_algorithm
for(int i=0; i<command.size(); i++)
{
switch(command[i])
{
case '*': case '+': case '-': case '/': case'(':
operators.push(command[i]);
break;
case ')':
while(operators.top() != '(')
{
output.push(operators.top());
operators.pop();
}
operators.pop();
break;
default:
output.push(command[i]);
break;
}
}
while(!operators.empty())
{
output.push(operators.top());
operators.pop();
}
while(!output.empty())
{
temp.push(output.top());
output.pop();
}
while(!temp.empty())
{
if(temp.top() == '+')
{
int a = atoi(&answer.top());
cout << "A=" << a << endl;
answer.pop();
int b = atoi(&answer.top());
cout << "B=" << b << endl;
answer.pop();
answer.push(b+a);
} else {
answer.push(temp.top());
}
temp.pop();
}
cout << answer.top() << endl;
system("pause");
return 0;
}
无论如何,问题是:如果我输入例如3 + 4,则结果为“&amp;”,当正确的结果为“7”时。那么,我的代码出了什么问题?
答案 0 :(得分:0)
替换此部分代码:
if(temp.top() == '+')
{
int a = atoi(&answer.top());
cout << "A=" << a << endl;
answer.pop();
int b = atoi(&answer.top());
cout << "B=" << b << endl;
answer.pop();
answer.push(b+a);
}
使用:
if(temp.top() == '+')
{
int a = answer.top() - '0';
cout << "A=" << a << endl;
answer.pop();
int b = answer.top() - '0';
cout << "B=" << b << endl;
answer.pop();
answer.push(b+a);
}
将解决您的问题。
答案 1 :(得分:0)
这里有两个问题。
首先:
int a = atoi(&answer.top());
atoi获取指向以null结尾的字符串的指针。但是&amp; answer.top()只是指向单个字符的指针。所以atoi将从该角色开始读取,然后继续在内存中行进,直到找到'\ 0'字符(或非数字)。根据您的平台上如何实现堆栈,这可能意味着它读取'4',然后是'3',然后是'\ 0',因此它最终为“43”。或者它可能会读取'4',然后是一些未初始化的内存,恰好以“8675309j”开头,因此它最终以“48675309”结束。
如果你想知道为什么编译器没有警告你这个错误,问题是C风格的字符串和指向单个字符的指针在语法上是完全相同的类型(char *),所以编译器可以'除非它理解atoi的语义,否则告诉你将它们混合起来。这是使用C ++字符串类和函数而不是基于C char *的函数更好的众多原因之一。
第二
answer.push(b+a);
b + a是一个int,但是你将它推入一堆字符。所以,即使它具有正确的价值,你也要推动角色'\ 007',而不是角色'7'。你需要重新串行它。但在这种情况下,你显然有类似于305419814的东西,当被转换为char时被截断为低8位(38),而38是'&amp;'。