【问题标题】:Printing x bytes from a text file per line until EOF每行从文本文件中打印 x 个字节,直到 EOF
【发布时间】:2014-11-02 08:45:06
【问题描述】:

所以我有一个已读取的文件。用户可以指定一次打印多少字节。
目前我有:

while(fread(buffer, bytes, 1, txtFile) != '\0')
    printf("%s\n", buffer);

但是,如果它首先到达 EOF,它会切断最后一行。例如,如果 bytes = 12 ,则打印:

How the migh
ty have fall

...但我希望它打印出来:

How the migh
ty have fall
en!

相反。这样做的正确方法是什么?

【问题讨论】:

    标签: c file-io fread


    【解决方案1】:

    fread 函数返回从文件中读取的items 数量。这个电话:

    fread(buffer, bytes, 1, txtFile)
    

    表示尝试读取大小为bytes 的项目。如果成功,则结果为1,如果失败,则结果为0。您写!= '\0' 的事实表明您可能误解了返回值。因为0 == '\0',它似乎适用于较早的行,但写0 是一种误导方式。

    由于文件中只剩下4 字节,它无法读取大小为12 字节的项目,因此您的循环退出。

    另一个主要问题是你调用printf("%s" 但是你没有提供一个字符串作为参数。 string 和 char 数组之间是有区别的。字符串以空终止符结尾,这就是printf 函数知道何时停止打印的方式。

    如果您阅读大小为1 的项目,那么您可以解决这两个问题,例如:

    for (size_t n_read; (n_read = fread(buffer, 1, bytes, txtFile)) > 0; )
    {
        buffer[n_read] = '\0';
        puts(buffer);
    }
    

    注意。确保分配 buffer 以使其中至少包含 bytes + 1 字节。

    【讨论】:

      【解决方案2】:

      由于最少读取长度不是 12 字节,原始代码失败,因此 fread() 返回 0。

      printf("%s\n", buffer); 不好,因为 buffer 没有明确地 '\0' 终止。

      修复:

      在每个fread() 之后,附加一个空字符。还要重新排序fread() 参数以记录部分读取。

      size_t bytes = 12;
      char buffer[bytes + 1];  // or char buffer[12 + 1];
      size_t cnt;
      
      while((cnt = fread(buffer, sizeof *buffer, bytes, txtFile)) > 0)
        buffer[cnt] = '\0';
        printf("%s\n", buffer);
      }
      

      另一种方法是将读取的数据简单地打印为char 的数组而不是字符串。

      size_t bytes = 12;
      char buffer[bytes];  // or char buffer[12];
      size_t cnt;
      
      while((cnt = fread(buffer, sizeof *buffer, bytes, txtFile)) > 0)
        for (size_t i = 0; i < cnt; i++) {
          fputc(buffer[i], stdout);
        }
        fputc('\n', stdout);
      }
      

      【讨论】:

        【解决方案3】:

        发生这种情况是因为在最后一行 '\0' 是第 4 个字节,因此 while loop 下的条件失败,退出 while。解决方案是在 while 之外打印 buffer values,以便打印最后 3 个字节。

        演示:

        while(fread(buffer, bytes, 1, txtFile) != '\0')
            printf("%s\n", buffer);
        printf("%s\n", buffer);
        

        【讨论】:

        • 打印en!have fall 而不仅仅是en! 有什么原因吗?
        • 是的,原因是每次缓冲区填充新值时,旧值都会被覆盖。在这种情况下,您的旧值是 ty have fall 并且只有 ty 被覆盖,其余的保持不变。尝试puts(buffer) 而不是第二个print 语句。
        • 谢谢,但它仍然会打印出en!have fall。有没有更好的办法解决这个问题?
        • 每次调用 printf() 后清除缓冲区为所有 '\0'
        猜你喜欢
        • 2015-05-18
        • 2021-07-25
        • 1970-01-01
        • 2012-05-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多