【问题标题】:Reading lines of a "text" file using fscanf() on cygwin在 cygwin 上使用 fscanf() 读取“文本”文件的行
【发布时间】:2012-07-20 14:49:02
【问题描述】:

考虑这段代码:

FILE * fp = fopen( filename, "r" );
int ret = fscanf(fp, "%d, %d, %d, %d, %d\n", &a, &b, &c, &d, &e);
if (ret != 5)
{
    // error and exit
}
long file_pos = ftell(fp);
printf("file position: %ld\n", file_pos);

正在读取的文件行是:

6, 5, 3, 2, 6\r\n  

也就是说,该文件具有 Windows 行结尾。

文件位置是 20,而我预计是 15。
但是,如果我将文件打开模式更改为二进制 ("rb"),则文件位置为 15,正如预期的那样。

在谷歌上搜索后,我找不到任何关于为什么会发生这种情况的线索,但只发现人们建议不要使用 fscanf()。

但我想知道为什么文件指针不在它应该在的位置。

【问题讨论】:

  • 你能读入并打印出文件的前 20 或 24 个字节(用"r" 打开)然后打印出来看看这些字节是什么吗?
  • 第一行之后是否还有其他空行可能会被格式字符串末尾的\n 占用?
  • @DanielFischer:内容还可以。但是进一步的解析出错了。 rb不是这样的
  • @twalberg:不,第一个之后没有空行。
  • @puffadder 问题是,这些字节是什么?如果前 15 个正好是 "6, 5, 3, 2, 6\r\n",那么接下来的是什么?

标签: c windows file-io cygwin


【解决方案1】:

fscanf 可能正在缓冲文件 - 即它读取某个大小的块,然后解析它以解码内容。

【讨论】:

  • 但是为什么缓冲/无缓冲的决定取决于文件打开方式呢?
  • @puffadder fscanf 不保证它在内部读取文件的操作 - 您可能会发现它在不同版本的 Windows 上预读取不同数量的字节。
  • 这是否意味着如果我使用 fscanf() 读取第一行,然后使用 fgets() + sscanf() 读取后续行,我可能会大吃一惊?
  • @puffadder 如果你混合使用 fscanf() 和 fgets() 那么奇怪的事情可能会发生
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-28
  • 1970-01-01
  • 1970-01-01
  • 2021-06-22
  • 2011-03-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多