【发布时间】:2019-06-02 17:15:51
【问题描述】:
我正在完成一项简单的任务:从 文件 中一次读取一行,打印该行并将所有内容附加到一个 char 数组中。这一切都始于我项目中的Segmentation fault (core dumped),然后我继续隔离我的代码,直到我达到这个:
#include <stdio.h>
#include <string.h>
int main(void)
{
FILE *fp;
fp = fopen("read.txt","r");
char buffer[255];
char longBuff[1024] = "";
while(fgets(buffer, 255, fp)) {
printf("%s\n",buffer);
strcat(longBuff, buffer);
}
fclose(fp);
printf("WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWTF%s\n", longBuff);
}
read.txt 文件:
short
this is Longer
+++++
sad
还有输出:
sad++is Longer
sad++is LongerWWWWWWWWWWWWWWWWWWWTFshort
当我满怀信心地期待时:
short
this is Longer
+++++
sad
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWTFshortthis is Longer+++++sad
我遇到过多个类似的问题,大多数答案都指向carriage return,但我仍然不明白这种行为以及它的原因是什么。
【问题讨论】:
-
我怀疑您使用的是 Unix/Linux,但打开了一个带有 Windows 行结尾的文本文件。尝试十六进制转储文本文件并查找 \r\n (0xD 0xA)。输出回车会将光标重置到行首。要解决此问题,您可以让您的程序删除回车,或修复文本文件以不包含它们
-
在
while (fgets(...))下方添加buffer[strcspn (buffer, "\r\n")] = 0; -
有趣的是,我在 Linux 上用
buffer[strcspn (buffer, "\r\n")] = 0;运行了你的代码,你的输入文件以 CRLF 结尾,我得到了你预期的输出。你有没有十六进制转储你的文件?你确定不是 UTF-16? -
这是一个猜测,但您是在 VS-Code 中创建原始文件,还是从 Internet 下载文件?使用
hexdump -Cv read.txt进行检查。这样您就可以查看文件中的字节。您还可以使用 Linuxfile实用程序来确定文件是什么,例如file read.txt。您的文件也可能有一个搞砸的 BOM(字节顺序标记)。你不会知道,直到你看。此外,为了消除一些谜团,buffer[strcspn (buffer, "\r\n")] = 0;所做的只是从buffer中修剪行尾。 (strcspn返回bufferNOT"\r\n"中的初始字符数) -
所有现代编辑器中都有选项允许使用
LF(换行Unix行结尾)、CRLF(回车换行DOS行结尾)和是的@987654341保存@(回车 Mac Pre-OSX 行结尾)。不知何故,你告诉gedit做后者(它应该默认为LF行尾)。当您说“从头开始创建”时,如果您刚刚打开gedit并键入了文件,保存后仍然以CR行结尾结束,您需要检查您的设置,以免再次发生这种情况。祝你编码顺利。