Does fscanf moves the passed file pointer ahead?
Asked Answered
T

4

5

I saw this code somewhere:

#include<stdio.h>

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

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

  return 0;
}

I expected that this will keep on printing the first word of the file in an infinite loop. I believed that file pointer is taken as input only to get the point from where input should be read and fscanf would have a local file pointer which it would use to read the file.

But on running I realized it actually prints the whole file. Only conclusion I can draw is that after reading the first input, it actually moves the passed file pointer ahead, otherwise it would have just kept on printing the first word again and again.

I saw the man documentation of fscanf but couldnt find anything regarding movement of file pointer after reading.

Can someone please explain or give a source where it is specified that the passed file pointer actually moves after reading ?

Thornberry answered 23/7, 2013 at 5:46 Comment(6)
I would suggest removing the C++ tag as nothing here is part of the C++ library or is idiomatic of C++ in anyway.Florence
@Florence Ahh, fine. Removed it.Thornberry
file pointer is used to indicate the read/write position in a file. So it obviously moves as you read the contents of the file :)Delanadelancey
@SanthoshPai Somehow I don't find it that obvious.Thornberry
Also note, however, that %s (without specifying a maximum length, such as %1023s", s) is basically like gets -- extremely dangerous because it does nothing to limit the input length and prevent buffer overflows.Freeswimming
@SanthoshPai, the file pointer doesn't point to a place in the file. It points to a structure with control information about the file, which indirectly includes the position.Fulmination
F
2

From the documentation: "Reads data from the stream..." this means it will act as other stream you read from. (http://www.cplusplus.com/reference/cstdio/fscanf/)

If you go to the definition of file (FILE - go to definition) you will get to this 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

where you can see sevral pointer (_base & _ptr) that will imply that FILE keeps pointers to both the begining of the file (for seeks, as with any other stream) and to the current location.

Fixture answered 23/7, 2013 at 5:57 Comment(0)
S
2

ftell returns the current file position for a stream and -1 on error.

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

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

fscanf returns the number of items converted and assigned. It returns EOF on error.

Steamship answered 23/7, 2013 at 6:3 Comment(0)
A
2

Since you are asking for reference, Here it is.

see Reading and writing files section of http://www.cs.cf.ac.uk/Dave/C/node18.html

see Moving the file pointer section of http://staff.um.edu.mt/csta1/courses/lectures/csa2060/c10.html

Appulse answered 23/7, 2013 at 6:5 Comment(0)
B
1

As you read/write a file, the file pointer is automatically incremented to indicate where the next character is to be written to or read from.

This statement :

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

tests whether end of file is reached or not.

You have a chance to enter infinite loop if the format of the input file was not as expected.

Bursa answered 23/7, 2013 at 6:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.