为什么在追加时添加 \n 字符可以打印出最后附加的行?

Why does adding a \n character while appending make it possible to print out the last appended line?

提问人:Rahul 提问时间:3/24/2019 最后编辑:CommunityRahul 更新时间:3/24/2019 访问量:80

问:

我正在尝试编写一些 C 代码,将一行文本附加到文件中,然后简单地逐行显示它。当我在追加模式下打开文件并使用 fprintf 添加一行时,该行会被添加,当我使用文本编辑器打开文件时,我可以看到它。但是,当我调用一个函数来显示所有行(在附加新文本之前工作正常)时,我得到所有行,直到最后一行,但不包括新的附加行。

这是我正在使用的代码。第一个函数只是添加一个新行,第二个函数只是读取所有行。read_csv() 最初在我没有通过代码附加任何行并且只是使用文本编辑器添加初始行时起作用。

void add_record(const char* csv_filename)
{
    FILE *f = fopen(csv_filename,"at");
    char str="My appended line "
    fprintf(f,"%s",str);
    fclose(f);

}
void read_csv(const char* csv_filename)
{
    FILE *f = fopen(csv_filename,"rt");
    char str[MAX];
    fgets(str,MAX,f);
    while(!feof(f))
      { fputs(str,stdout);
        fputs("\n",stdout);
        fgets(str,MAX,f);
      }
    fclose(f);
    
}

现在我找到了两个解决我的问题的方法,但我并不完全明白它们为什么有效。

修复 1 :当我尝试显示它时,添加额外的 fgets() 会打印缺少的附加行,但是当我使用它显示我的原始文本文件时,它会打印最后一行两次。所以不是一个好的解决方案。

fgets(str,MAX,f)
while(!feof(f))
      { fputs(str,stdout);
        fputs("\n",stdout);
        fgets(str,MAX,f);
      }
   fgets(str,MAX,f)

修复2:在附加的字符串中添加一个新行字符可以完美地解决问题,并且一切都很顺利。当我调用 read_csv() 时,所有行都会显示出来。

char str="My appended line "
    fprintf(f,"%s\n",str)

查看 fgets() 的文档,它说它会一直读取,直到到达新行字符或 eof(以先发生者为准),所以我不明白为什么我的附加行被 fgets() 忽略。

fgets() 到达最后一行(它跳过)时,我认为情况是这样的:它得到一个带有“text text text eof”的字符串,并且它跳过了 print 语句的循环。但是当我在 while 循环之外使用额外的 fgets() 时,它起作用了。此外,当我添加一个新行并且情况是像“text text text \n eof”这样的字符串时,它不会退出循环并继续显示它。

如果我能获得一些关于正在发生的事情以及为什么这两个修复程序有效的信息,我将不胜感激。我怀疑这与 feof 检测 eof 或有关 fgets 的一些细节有关,但我在网上找不到任何令人满意的东西。

非常感谢您抽出宝贵时间阅读和回复。

C file-io append fgets feof

评论

2赞 KamilCuk 3/24/2019
while(!feof(f))总是错的,你没有读到最后一行之后。为什么不检查 的返回值?fgets
0赞 Rahul 3/24/2019
感谢您的回复。我能问为什么 while 条件总是错的吗?因为如果我在附加一行之前调用它,它会完美地显示所有行。
0赞 KamilCuk 3/24/2019
因为 then 不会设置,因为它在读取换行符后退出。因此,未设置条件,因为流未读取 eof。然后下一个读取零个字符并设置的 feof。fgetsfeoffeoffgets
0赞 ShadowRanger 3/24/2019
为什么“while (!feof(file))”总是错的?
0赞 Rahul 3/24/2019
我尝试检查fgets()的返回值,退出循环后它是NULL,这意味着它到达了文件末尾,对吗?

答: 暂无答案