C语言用fgets读取文本文件:非\0与\n的神秘字符排查及解决
fgets读取文本后strcmp不匹配的原因与解决办法
问题场景
我查遍了相关内容,还是遇到了这个问题:
我的C代码里定义了常量ESCAPE = "1a2b3c4e5d",用fgets读取backup.txt的内容,文件第一行是1a2b3c4e5d\r\n(Windows格式换行)。尝试去除换行符后和ESCAPE做strcmp,始终匹配失败。
相关代码片段:
const char *ESCAPE= "1a2b3c4e5d"; FILE *FP= fopen("backup.txt", "r"); char line[64]; while(fgets(line, sizeof(line), FP)){ fprintf(stdout, "this is line lenght: %ld", strlen(line)); // 输出结果为12 line[strlen(line) -1]= 0; // 尝试去除换行符 fprintf(stdout, "This is line after getting rid of new_line: %ld\n", strlen(line)); // 输出结果为11 fprintf(stdout, "This is ESCAPE lenght: %ld\n", strlen(ESCAPE)); // 输出结果为10 if(strcmp(line, ESCAPE) == 0){ fprintf(stdout, "I'm Here\n"); } }
按预期,第一行10个有效字符加\n应该是11长度,去除后应该是10,但实际去除后长度是11,导致strcmp无法匹配。
原因分析
这个"神秘字符"是回车符\r。Windows系统的文本文件换行采用\r\n(回车+换行)组合,fgets会把这两个字符都读入缓冲区。原代码只去掉了最后一个\n,但\r仍留在字符串中,导致长度多1,strcmp自然无法匹配。
解决方案
使用strcspn函数一次性处理\r和\n,替换原有的去除换行代码:
line[strcspn(line, "\r\n")] = '\0';
strcspn会返回字符串中第一个属于"\r\n"集合的字符的位置,直接将该位置设为字符串终止符,不管是单个\n、单个\r还是\r\n组合,都能一次性清理干净。
补充说明
部分操作系统课程可能未提及\r字符的存在,这个方案对遇到相同跨平台文本换行问题的开发者会很有用。
内容的提问来源于stack exchange,提问作者ZODIACK
相关产品推荐
相关产品推荐

