fscanf是否会移动传递的文件指针?

5

我在某处看到了这段代码:

#include<stdio.h>

int main()
{
    FILE * fp;
    char s[1024];
    fp = fopen("file","r");

    while( fscanf(fp, "%s", s ) != EOF )
    {
        puts(s);
    }

  return 0;
}

我原以为这会在一个无限循环中不断打印文件的第一个单词。我认为文件指针只是被用作输入的起点,而fscanf将具有一个本地文件指针,它将用于读取文件。
但是运行后,我意识到它实际上打印了整个文件。唯一的结论是,在读取第一个输入后,它实际上将传递的文件指针向前移动,否则它将继续不停地打印第一个单词。
我查看了fscanf的手册,但没有找到任何关于读取后文件指针移动的内容。
请问是否有人能够解释或提供源代码,说明传递的文件指针实际上是在读取后移动的呢?

1
我建议删除C ++标签,因为这里没有任何属于C ++库的部分,也不以任何方式符合C ++的习惯用法。 - Borgleader
@Borgleader 哦,好的。已经移除了。 - Amit Tomar
文件指针用于指示文件中的读/写位置。因此,当您读取文件内容时,它显然会移动 :) - Santhosh Pai
@SanthoshPai,不知道为什么,我觉得这并不是那么明显。 - Amit Tomar
2
请注意,%s(未指定最大长度,例如%1023s)基本上类似于gets——极其危险,因为它不限制输入长度或防止缓冲区溢出。 - Jerry Coffin
@SanthoshPai,文件指针并不指向文件中的某个位置。它指向一个包含有关该文件控制信息的结构体,该结构体间接包括该位置。 - ugoren
4个回答

2

根据文档:“从流中读取数据…”,这意味着它会像你从其他流中读取的那样运作。(http://www.cplusplus.com/reference/cstdio/fscanf/

如果你查看文件(FILE - 转到定义),你会得到这个typedef

#ifndef _FILE_DEFINED
struct _iobuf {
        char *_ptr;
        int   _cnt;
        char *_base;
        int   _flag;
        int   _file;
        int   _charbuf;
        int   _bufsiz;
        char *_tmpfname;
        };
typedef struct _iobuf FILE;
#define _FILE_DEFINED
#endif

您可以看到几个指针(_base和_ptr),这意味着FILE保留了指向文件开头(用于搜索,与任何其他流一样)和当前位置的指针。


2

ftell函数返回流的当前文件位置,如果出现错误则返回-1

while( fscanf(fp, "%s", s ) != EOF )
{

    printf("%s>%ld\n", s, ftell(fp));
}

fscanf 返回转换和分配的项目数量。如果出错,它返回EOF。


2

1
当你读写文件时,文件指针会自动递增,以指示下一个字符应该被写入或读取。
这个语句:
while( fscanf(fp, "%s", s ) != EOF )

测试是否已到达文件结尾。

如果输入文件的格式不符合预期,您有可能进入无限循环。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接