未指定换行符,为何C语言打印语句会输出两行?
问题原因与修复方案
嗨,这个问题我太熟悉了!核心是**fgets()的读取特性**和你打印语句里的换行符叠加导致的,咱们一步步拆解:
fgets()会保留换行符:当fgets从文件读取每行内容时,它会把行尾的\n(换行符)也一并读到缓冲区buf里。比如你目标文件里的echo 1,实际被读取到的内容是echo 1\n。- 双重换行触发分行:你的
fprintf语句最后还加了一个\n,这就相当于先输出buf里的内容(自带一个换行),紧接着又输出了一个额外的换行——两个连续的换行符自然就把每条提示拆成了两行显示。
怎么验证?
你可以加一行调试代码,看看buf的真实内容:
#include <stdio.h> #include <string.h> int main(int argc, char **argv) { FILE *file = fopen(argv[1], "r"); char buf[100]; while (fgets(buf, sizeof(buf), file)) { // 打印buf的十六进制,能看到末尾的0x0a(就是换行符) for(int i=0; buf[i]!='\0'; i++) { printf("%02x ", (unsigned char)buf[i]); } printf("\n"); fprintf(stderr, "%s: unparseable line: '%s', ignored\n", argv[0], buf); } fclose(file); return 0; }
运行后你会发现每行末尾都有0a这个十六进制值,对应的就是换行符\n。
两种修复方式任你选
- 方式一:去掉
fgets读取到的换行符:在打印前把buf里的换行符替换成字符串结束符\0,推荐用strcspn函数,简洁又安全:while (fgets(buf, sizeof(buf), file)) { // strcspn返回第一个'\n'的位置,直接替换成结束符 buf[strcspn(buf, "\n")] = '\0'; fprintf(stderr, "%s: unparseable line: '%s', ignored\n", argv[0], buf); } - 方式二:去掉
fprintf里的额外换行:如果不需要额外的换行,直接删掉语句最后的\n,这样就只输出buf里自带的那一个换行,不会叠加:fprintf(stderr, "%s: unparseable line: '%s', ignored", argv[0], buf);
顺便提一句,你的代码里没有检查fopen的返回值,如果运行时没传对文件名或者文件不存在,会直接崩溃,建议加上:
FILE *file = fopen(argv[1], "r"); if (!file) { fprintf(stderr, "Failed to open file: %s\n", argv[1]); return 1; }
内容的提问来源于stack exchange,提问作者user9314692
相关产品推荐
相关产品推荐

