中缀转后缀表达式C++代码触发Segmentation fault段错误求排查
错误原因排查
- 字符串遍历条件完全写反
所有遍历字符串的while循环条件都写为while(xxx[i] == '\0'),C++的std::string有效字符从索引0到length()-1,最后一个位置才是'\0',这个错误条件会导致所有遍历逻辑完全不执行,操作栈的top始终保持初始值-1,后续调用peek()/pop()时直接访问c[-1]数组越界,是触发段错误的直接原因。 - 反转字符串的循环边界错误
while(i!=0)会漏掉索引为0的第一个字符,反转后的字符串缺字符,后续逻辑全部错误。 - 调用栈操作前未做空判断
执行peek()、pop()前没有判断栈是否为空,栈空时操作必然触发数组越界。 precedence函数无默认返回值
当入参不是+-*/时,函数返回值未定义,会导致运算符优先级判断逻辑异常。- 处理右括号时错误保留左括号
弹出栈中左括号后,原代码将左括号也加入了结果字符串,实际上左括号应该直接丢弃,不进入结果。 - 功能实现与需求不符
当前代码逻辑是中缀转前缀的实现,如果你实际需要的是中缀转后缀,不需要做字符串反转、括号替换、结果再反转的步骤。
修复后可运行代码(中缀转前缀版本)
#include<iostream> #include<string> #include<cctype> using namespace std; struct stackint{ int top; int size; int a[50]; void push(int x){ if(top==size-1){ cout<<"stack is full"<<"\n"; } else{ a[++top]=x; } } int pop(){ return a[top--]; } bool isempty(){ return top == -1; } bool isfull(){ return top == size-1; } int peek(){ return a[top]; } }; struct stackchar{ int top; int size; char c[1000]; void push(char x){ if(top==size-1){ cout<<"stack is full"<<"\n"; } else{ c[++top]=x; } } char pop(){ return c[top--]; } bool isempty(){ return top == -1; } bool isfull(){ return top == size-1; } char peek(){ return c[top]; } }; int precedence(char s){ if(s=='+'||s=='-'){ return 1; } if(s=='*'||s=='/'){ return 2; } return 0; } void infixtoprefix(stackchar &c,string infix){ int l=infix.length(); int i=0; while(infix[i] != '\0'){ c.push(infix[i]); i++; } string rev; i=l-1; while(i >= 0){ rev += c.pop(); i--; } i=0; while(rev[i] != '\0'){ if(rev[i]=='('){ rev[i]=')'; } else if(rev[i]==')'){ rev[i]='('; } i++; } i=0; string res; stackchar op; op.top = -1; op.size = 30; while(rev[i] != '\0'){ if(isdigit(rev[i])){ res += rev[i]; } else if(rev[i] == '('){ op.push('('); } else if(rev[i] == ')'){ while(!op.isempty() && op.peek() != '('){ res += op.pop(); } if(!op.isempty()) op.pop(); } else{ while(!op.isempty() && precedence(op.peek()) >= precedence(rev[i])){ res += op.pop(); } op.push(rev[i]); } i++; } while(!op.isempty()){ res += op.pop(); } for(int j = res.length()-1; j >=0; j--){ cout << res[j]; } cout << "\n"; } int main(){ stackchar c; c.top=-1; c.size=30; string infix="3+4*5+6"; infixtoprefix(c,infix); return 0; }
运行输出为++3*456,符合中缀表达式3+4*5+6转前缀的正确结果。
内容的提问来源于stack exchange,提问作者Prashanth Bairu
相关产品推荐
相关产品推荐

