C语言parser函数调用strcmp对比相同字符串返回错误值问题求助
问题根因
- 输入携带换行符:你使用
fgets读取用户输入时,会将输入末尾的换行符\n一同存入缓冲区。比如输入swp后按回车,实际instruction数组中存储的内容是"swp\n",你仅用空格作为分隔符调用strtok,得到的首个分词结果是包含换行符的"swp\n",和目标常量字符串"swp"内容不一致,因此strcmp匹配失败。
- 输入携带换行符:你使用
- 变量未初始化:
parser函数中定义的局部变量i没有设置初始值,直接执行array[i++]写入分词结果时,i是随机垃圾值,会导致分词结果写入数组的位置完全错误,属于C语言未定义行为,即使没有换行符问题也无法正常匹配。
- 变量未初始化:
- 非法访问未初始化内存:分词循环中直接打印
array[1]、array[2],如果输入分词后不足3个元素,这两个位置都是未初始化的野指针,打印操作会触发未定义行为,可能导致程序崩溃或输出乱码。
- 非法访问未初始化内存:分词循环中直接打印
- 额外说明:你给出的预期输出有误,
swp属于aCouple数组的元素,匹配成功后应该输出aCouple detected,而不是你写的hCouple detected。
修复步骤
- 读取输入后清除末尾的换行符,在
fgets调用后、parser调用前添加代码,删除换行符:
instruction[strcspn(instruction, "\n")] = '\0';
- 初始化
parser中的变量i,定义时直接赋值为0:
int i = 0;
- 修改
strtok的分隔符配置,新增换行符作为分隔符,双重避免换行符干扰:
char* p = strtok(stream, " \n"); // 后续第二次调用strtok也同步修改分隔符 p = strtok(NULL, " \n");
- 修改分词打印逻辑,仅打印实际存在的分词结果,避免访问未初始化的数组元素,同时增加边界判断避免
array数组越界:
while (p != NULL && i < 3) { // 限制最多存3个分词,避免越界 array[i++] = p; index = index + 1; p = strtok(NULL, " \n"); } // 循环外统一打印,根据实际分词数量输出 printf("parser detects:"); for(int j=0;j<index;j++){ printf(" %s", array[j]); } printf("\n");
- 补充
parser函数的兜底返回值,所有匹配都失败时添加return -1;避免编译器警告。
修复后核心代码示例
// main中读取输入部分 char instruction[512]; printf("instruction: \n"); fgets(instruction,512,stdin); // 清除换行符 instruction[strcspn(instruction, "\n")] = '\0'; parser(instruction); // 修复后的parser函数 int parser(char* stream) { char* aCouple[3] = {"neg","swp","sav"} ; const char* hCouple[2] = {"add","sub"} ; char* pCouple[1]= {"mov"}; int i = 0; // 初始化i int index = 0; char* p = strtok (stream, " \n"); char* array[3]; while (p != NULL && i < 3) { array[i++] = p; index = index + 1; p = strtok (NULL, " \n"); } // 打印检测到的分词 printf("parser detects:"); for(int j=0;j<index;j++){ printf(" %s", array[j]); } printf("\n"); for(i =0; i <=2; i++) { printf("comparing with index value %u i.e the element called %s \n", i, aCouple[i]); if (strcmp(array[0],aCouple[i]) == 0) { printf("aCouple detected\n"); return 0; } } for (i =0; i <=1; i++) { printf("comparing with index value %u i.e the element called %s \n", i, hCouple[i]); if (strcmp(array[0],hCouple[i]) == 0) { printf("hCouple detected\n"); return 0; } } for (i =0; i<= 0; i++) { printf("comparing with index value %u i.e the element called %s \n", i, pCouple[i]); if (strcmp(array[0],pCouple[i]) == 0) { printf("pCouple detected\n"); return 0; } } printf("failed to find a single match\n"); return -1; }
修复后输入swp会正确匹配aCouple的第二个元素,输出aCouple detected。
内容的提问来源于stack exchange,提问作者Bilal Ahmed
相关产品推荐
相关产品推荐

