使用atoi()转换数值始终为0,一阶方程计算程序故障排查求助
一阶方程计算程序atoi转换后结果始终为0的原因及修复方案
我正在编写一个一阶方程计算程序,因方程包含字符与操作符,需将数据存入字符串后通过atoi()转换为整数,但计算结果始终为初始值0。相关代码如下:
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> int main() { char equation[10]; scanf("%s", equation); int length = strlen(equation); char operands[7]; int op_index[7]; int op_amount = 0; for(int i = 0; i < length; i++){ if(equation[i] == '*' || equation[i] == '/' || equation[i] == '+' || equation[i] == '-'){ operands[op_amount] = equation[i]; op_index[op_amount] = i; op_amount++; } } char nums1[3]; char nums2[3]; int i = op_index[0] - 1; int j = 3; int ans = 0; while(isdigit(equation[i]) != 0){ nums1[j] = equation[i]; j--; i--; } i = op_index[0] + 1; j = 0; while(isdigit(equation[i]) != 0){ nums2[j] = equation[i]; j++; i++; } if(operands[0] == '*'){ ans = atoi(nums1) * atoi(nums2); } else if(operands[0] == '/'){ ans = atoi(nums1) / atoi(nums2); } else if(operands[0] == '+'){ ans = atoi(nums1) + atoi(nums2); } else if(operands[0] == '-'){ ans = atoi(nums1) - atoi(nums2); } printf("ans = %d", ans); }
核心问题分析
- 字符串缺少结束符:
atoi()只能识别以'\0'结尾的合法C字符串,你定义的nums1和nums2在存储数字字符后没有添加结束符,导致atoi()无法解析出有效整数,直接返回0。 - nums1下标越界+存储顺序错误:
nums1长度为3,合法下标是0-2,但你初始化j=3,第一次赋值就会越界破坏内存;同时你从右往左把数字存入nums1,最后得到的是逆序字符,既没有修正顺序也没有结束符,atoi()完全无法识别。 - 数组长度不足:
nums1和nums2仅定义了3个字符的空间,若输入的数字超过两位(比如123+45),会再次触发越界问题。
修复后的代码
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> int main() { char equation[20]; // 扩大数组,避免输入过长溢出 scanf("%s", equation); int length = strlen(equation); char operands[7]; int op_index[7]; int op_amount = 0; for(int i = 0; i < length; i++){ if(equation[i] == '*' || equation[i] == '/' || equation[i] == '+' || equation[i] == '-'){ operands[op_amount] = equation[i]; op_index[op_amount] = i; op_amount++; } } // 先判断是否找到操作符,避免op_index[0]越界 if(op_amount == 0){ printf("未找到有效操作符\n"); return 1; } char nums1[10], nums2[10]; // 扩大数字数组长度 int i = op_index[0] - 1; int j = 0; // 从操作符左侧往回收集数字,先存逆序 while(i >= 0 && isdigit(equation[i])){ nums1[j] = equation[i]; j++; i--; } // 反转得到正确顺序的数字字符串 for(int k = 0; k < j/2; k++){ char temp = nums1[k]; nums1[k] = nums1[j-1-k]; nums1[j-1-k] = temp; } nums1[j] = '\0'; // 添加字符串结束符 i = op_index[0] + 1; j = 0; // 收集操作符右侧的数字,正序存储 while(i < length && isdigit(equation[i])){ nums2[j] = equation[i]; j++; i++; } nums2[j] = '\0'; // 添加字符串结束符 int ans = 0; if(operands[0] == '*'){ ans = atoi(nums1) * atoi(nums2); } else if(operands[0] == '/'){ // 增加除数不为0的校验 int num2 = atoi(nums2); if(num2 == 0){ printf("除数不能为0\n"); return 1; } ans = atoi(nums1) / num2; } else if(operands[0] == '+'){ ans = atoi(nums1) + atoi(nums2); } else if(operands[0] == '-'){ ans = atoi(nums1) - atoi(nums2); } printf("ans = %d\n", ans); return 0; }
修复要点说明
- 给
nums1和nums2添加了字符串结束符'\0',确保atoi()能正确解析数字字符串。 - 调整
nums1的存储逻辑:先逆序收集字符,再反转得到正确顺序的数字,同时修正了下标越界问题。 - 扩大了数组长度,避免输入过长导致的内存溢出。
- 添加了操作符存在性判断和除数不为0的校验,提升程序健壮性。
内容的提问来源于stack exchange,提问作者a573263
相关产品推荐
相关产品推荐

