Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does fgets() keep track of what line it's on?

Tags:

c

file

stream

This code correctly reads a file line-by-line, stores each line in line[] and prints it.

int beargit_add(const char* filename) {
    FILE* findex = fopen(".beargit/.index", "r");

    char line[FILENAME_SIZE];
    while(fgets(line, sizeof(line), findex)) {
        strtok(line, "\n");
        fprintf(stdout, "%s\n", line);
    }
    fclose(findex);
    return 0;
}

However, I am baffled as to why using fgets() in the while loop actually reads the file line-by-line. I am brand new to C after having learned Python and Java.

Since each call to fgets() is independent, where is C remembering which line it is currently on each time you call it? I thought it might have to do with changing the value FILE* index points to, but you are passing the pointer into fgets() by value so it could not be modified.

Any help in understanding the magic of C is greatly appreciated!

like image 976
rosstex Avatar asked Jan 09 '23 23:01

rosstex


2 Answers

It's not fgets keep track, findex does this for you

findex is a FILE type, which includes infomation about a open file such as file descriptor, file offset

FILE is a encapsulation of I/O in OS.

more about: FILE

Object type that identifies a stream and contains the information needed to control it, including a pointer to its buffer, its position indicator and all its state indicators.

and the offset is to keep track of the file, each time you read the file, it starts from the offset. All these work are done by FILE, it do for you, and for fgets

more info about offset offset wiki

like image 188
simon_xia Avatar answered Jan 14 '23 20:01

simon_xia


I thought it might have to do with changing the value FILE* index points to

it's not the value of the pointer itself that is changed. The pointer points to a structure (of type FILE) which contains information about the stream associated with that structure/pointer. Presumably, one of the members of that structure contains a "cursor" that points to the next byte to be read.

Or maybe it's just got a file descriptor int (like on many Unices) and I/O functions just call out to the kernel in order to obtain information about the file descriptor, including the current position.

like image 24
The Paramagnetic Croissant Avatar answered Jan 14 '23 22:01

The Paramagnetic Croissant