strcmp函数异常?链表文件读写作业中分割操作符识别失败求助
看起来你在做链表操作的作业时碰到了字符串分割的坑——我之前处理类似文件读取的需求时也踩过一模一样的雷,大概率是字符串未正确终止或者藏了看不见的空白字符导致的,毕竟strcmp()完全依赖字符串末尾的'\0'来判断结束位置,哪怕打印出来看起来正常,内存里的情况可能完全不一样。
核心原因&对应解决步骤
分割后的op_code没加字符串终止符
如果你是手动从行尾截取操作符(比如直接取最后一个字符),一定要记得给op_code手动补上'\0'。比如:char op_code[2]; // 假设line是读取到的一行内容 op_code[0] = line[strlen(line)-1]; op_code[1] = '\0'; // 这步绝对不能省!要是漏掉这步,
strcmp(op_code, "a")的时候会一直往内存后面读,直到碰到随机的'\0',结果完全不可控,甚至会出现“在op_code附近加字符就异常”的情况——因为你加的字符改变了后续内存的随机内容,影响了strcmp的读取。op_code包含隐藏的空白字符(换行、回车、空格)
文件里的每一行末尾大概率有换行符'\n'或者回车'\r',如果你直接取最后一个字符,可能拿到的不是'a'或'd',而是这些看不见的控制字符,但打印的时候只会显示换行,看起来像是正常的操作符。
最稳妥的办法是按空格分割内容(毕竟你的格式是“姓名 操作符”),用strtok自动处理空白和换行:char line[100]; // 假设行长度足够 fgets(line, sizeof(line), fp); // 按空格、换行、回车分割,先拿姓名 char *name = strtok(line, " \n\r"); // 再拿操作符 char *op_code = strtok(NULL, " \n\r");这样分割出来的
name和op_code都是自带'\0'的合法字符串,strcmp就能正常识别了。op_code的定义方式不对
如果你把op_code定义成单个字符char op_code;,然后用strcmp(&op_code, "a"),这肯定会出问题——strcmp要求传入的是字符串(带终止符),单个字符后面没有'\0',函数会直接越界读取内存,行为完全不可预测。一定要把op_code定义成至少长度为2的数组:char op_code[2];,这样才能装下操作符字符+终止符。
快速排查验证方法
你可以打印op_code的ASCII码来确认是不是隐藏字符:
printf("op_code字符的ASCII值:%d\n", op_code[0]);
正常的'a'是97,'d'是100;如果是'\n'是10,'\r'是13,空格是32——一看就能知道是不是有问题。另外也可以用strlen(op_code)看长度,如果长度不是1,那要么是没加终止符,要么是藏了多余字符。
内容的提问来源于stack exchange,提问作者Tristan Shepherd

