2

我目前正在编写一段代码,该代码将函数作为字符串从用户输入,将其转换为后缀表达式,然后将其转换为中缀,然后计算表达式。

这是一项正在进行的工作,但我在这个过程中面临着一个问题。只有当数字是一个一位数的整数时,程序才起作用。例如,如果系数是50或1.4,就会给我一个错误。

我试了几次,但每次都会出错。

我试图单独拆分每个整数,然后将其重新分组:

#包括<ctype.h>#包括<string.h>#包括<stdlib.h>#包括<stdio.h>#包括<math.h>typedef结构标记{int类型;int值;双值1;int三角;整数预处理;struct标记*next;}代币;typedef结构{双项目[200];int顶部;//双顶1;struct Stack*前一个;}堆叠;void printStack(堆栈){printf(“堆栈:”);for(int i=0;i<=s->顶部;i++){if(是数字->项目[i]){printf(“%d”,s->项目[i]);}其他{printf(“%c”,s->项目[i]);}}printf(“\n”);}double evaluate_postfix(堆栈*后缀,double*x){堆栈eval_Stack;初始化(&eval_stack);for(int i=0;i<=后缀->顶部;i++){char标记=后缀->项[i];if(isdigit(标记)){j=1;双tmp=标记-“0”;while(isdigit(后缀->项[i+j]){tmp=tmp*10+(后缀->项[i+j]-“0”);j++;}i=i+j-1;推送(&eval_stack,tmp);//将char转换为int..}无效中缀_to_postfix_and_evaluate(){堆栈中缀,中缀;初始化(&infixtmp);初始化(中缀);标记*tmp=头部;while(tmp!=空){交换机(tmp->类型){案例T_NUMBER:push(中缀,tmp->value1+'0');//将int转换为char断裂;...}无效define_type(){整数j=0;//从0开始j以处理循环中的初始数字if(isdigit(函数[i])){nexttoken->类型=T_NUMBER;nexttoken->value1=函数[i]-“0”;}

我也试着先把它们分组,但那也没用。。。

无效define_type(){整数j=1;if(isdigit(函数[i])){nexttoken->类型=T_NUMBER;nexttoken->value=函数[i]-“0”;while(isdigit(函数[i+j])){nexttoken->value=nexttocken->value*10+(函数[i+j]-'0');j++;}i=i+j-1;
2
  • 欢迎使用StackOverflow。请拿一个旅游并查看如何提问具体来说:你发布了很多代码。发布最小可再现示例将帮助我们帮助你。 评论 5月22日8:44
  • 在将所有数字字符串放入堆栈之前,应该将其转换为内部类型。这将允许超过一个数字,并且还可以处理浮点rtypes。使用字符串转换为整数,自动变速器等C库函数来帮助您。 评论 5月22日9:40

1答案1

重置为默认值
1

我不知道你为什么要把字符放在一个双精度数组中。

如果我迭代一个字符数组,如:

void DoParse(char*pszFormula,无符号nLength){浮动fNum=-1;for(无符号i=0;i<nLength;i++){如果((fNum>=0)&&!isdigit(pszFormula[i]){printf(“Fnum:%f\n”,Fnum);fNum=-1;}开关(pszFormula[i]){大小写“+”:大小写“-”:案例“*”:大小写“/”:printf(“找到运算符%c\n”,pszFormula[i]);断裂;违约:if(是数字(pszFormula[i]){fNum=(fNum>=0?fNum*10:0)+(pszFormula[i]-'0');}断裂;}}如果(fNum>=0){printf(“最后一个fNum:%f\n”,fNum);}}

输入103+34*26给了我:

编号:103.000000找到操作员+编号:34.000000找到操作员*最后一个fNum:26.000000

输入43-64/6给了我:

金额:43000000找到操作员-编号:64.000000已找到运算符/最后一个fNum:6.000000

如果我想支持非整数参数,我需要自动变速器就像OldBoy建议的那样。

void DoParse(char*pszFormula,无符号nLength){char szNum[12];成员集(szNum,0,sizeof(szNum));for(无符号i=0;i<nLength;i++){开关(pszFormula[i]){大小写“+”:大小写“-”:案例“*”:大小写“/”:if(*szNum&&!是数字(pszFormula[i])){浮点f=atof(szNum);printf(“找到一个数字:%f\n”,f);/*净化缓冲器*/成员集(szNum,0,sizeof(szNum));}printf(“找到运算符%c\n”,pszFormula[i]);断裂;大小写“.”:/*将点附加到num缓冲区*/szNum[strlen(szNum)]=pszFormula[i];断裂;违约:if(是数字(pszFormula[i]){/*向num缓冲区追加数字*/szNum[strlen(szNum)]=pszFormula[i];}断裂;}}if(*szNum){浮点f=atof(szNum);printf(“找到的最后一个数字:%f\n”,f);}}

类似输入94.3+43.4/42现在给出:

找到一个号码:94.30003找到操作员+找到一个号码:43.40002找到操作员/找到的最后一个数字:42.000000

您也可以尝试使用斯特托克sscanf公司.

调试您的定义_类型方法是让它接受一个输入参数,而不是使用一个全局变量。这样,您可以快速测试各种字符串。从一个简单的整数参数开始,然后是小数,最后是逐渐复杂的表达式。

你的答案

单击“发布您的答案”,表示您同意我们的服务条款并确认您已阅读我们的隐私政策.

不是你想要的答案吗?浏览已标记的其他问题问你自己的问题.