Search code examples
cfseekftellfgetpos

Are fgetpos() and fsetpos() only for text mode? What location/offset data is the fpos_t object filled with if not number of bytes?


I understand the workings of ftell() and fseek() in C, but for this question I couldn't find any precise answer anywhere, including from the closest post on StackOverflow(LINK).

So can you please answer the following:

  • Can it be concluded that fgetpos() and fsetpos() are relevant only for text files opened in text mode, and not for files opened in binary mode?
  • What kind of position information is the fpos_t object filled with by fgetpos(), given that it is not a long integer offset etc. like the one given by ftell()? The site cplusplusreference only tells the following:

The function fills the fpos_t object pointed by pos with the information needed from the stream's position indicator to restore the stream to its current position


Solution

  • fgetpos() and fsetpos() are relevant for both text and binary mode.

    The advantage of fgetpos() is that is keeps the full position in the stream, including its internal state, so that you can restore is later. This works whether you are in text mode or not. This is especially important if you are using wide oriented streams or mix fgetc() and fgetwc() in the same file, because some locale use a state dependent multibyte encoding (state depends on previous reads).

    fseek() and ftell() can also work with text and binary mode. However there is an important restriction in text mode: you should only use fseek() with 0 or a value previously returned by ftell() (in binary mode you can use whatever value you want). This is because the text mode reading can change the number of bytes returned from reading compared to the bytes effectively in the file (typical example, the 2 CR+LF bytes in a windows file which are converted to a signe LF byte).

    As ftell() only returns a long int offset, it can't keep track of the multibyte state if this would be needed. So using fseek() might loose this state.