每行从文本文件打印x个字节,直到EOF

时间:2014-11-02 08:45:06

标签: c file-io fread

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

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!

代替。这样做的正确方法是什么?

3 个答案:

答案 0 :(得分:2)

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

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);
}

NB。确保buffer被分配为至少有bytes + 1个字节。

答案 1 :(得分:1)

原始代码失败,因为最小读取长度不是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);
}

答案 2 :(得分:0)

这是因为在最后一行'\0'是第4个字节,因此下的条件 循环失败,退出 。解决方案是在之外打印缓冲区值 ,以便打印最后3个字节。

演示:

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