I'm starting to learng C and i'm using text files. Loading text from them, work with it and then updating it in the same file. I was told that fseek() is not guaranteed to work everytime in text files, and i can't truly understand why. If someone could explain this it would be great!!
I also found that if you do
pos = ftell(file);
fseek(pos);
it's guaranteed to move the pointer to "pos". Is this right?
CodePudding user response:
Ffseek() is used to move file pointer associated with a given file to a specific position.syntax :fseek(FILE *pointer, long int offset, int position),offset: number of bytes to offset from position , position: position from where offset is added. position defines the point with respect to which the file pointer needs to be moved. It has three values: SEEK_END : It denotes end of the file. SEEK_SET : It denotes starting of the file. SEEK_CUR : It denotes file pointer’s current position. // Moving pointer to end We need to specify postion fseek(fp, 0, SEEK_END); // Printing position of pointer
printf("%ld", ftell(fp)); What the thing you have return is also write but specifiying offset position is much better
CodePudding user response:
I was told that
fseek()
is not guaranteed to work every time in text files.
This is true, but an explanation is required:
Some legacy systems use multiple bytes to encode the end of line in text files, or some other scheme such as fixed length records... This makes file offsets differ from the number of bytes read from the stream. In fact, some file offsets are meaningless in text files, such as the offset of the LF
byte in a CR
/LF
sequence. This feature is also a problem when writing text files and is more so in update mode when using the same stream pointer to read and write to the same file.
This was never a problem on Unix systems where text files and binary files are just sequences of bytes and line endings represented by a single newline byte.
When porting the C language to other operating systems, compiler vendors came up with various elaborate tricks to handle the translation of system specific line endings to a single '\n'
byte.
As these tricks where system specific or even vendor specific, no standard approach could be standardized in 1989 when the ANSI drafted the first C Standard. They just agreed on the t
and b
flags for the fopen()
mode argument and removed any constraint on the meaning of the return value of ftell()
beyond this simple constraint:
For a text stream, either offset
shall be zero, or offset
shall be a value returned by an earlier successful call to the ftell
function on a stream associated with the same file and whence
shall be SEEK_SET
.
Note that fseek(pos);
in your question is incorrect as the stream and whence argument are missing. You should write:
long pos = ftell(file);
...
fseek(file, pos, SEEK_SET); // move back to position <pos>
Note however that fseek()
can fail for other reasons: not all streams support seeking, such as pipes, terminal connections and other character devices...