Search code examples
clanguage-lawyerfopenfseek

Can I read from the beginning a file open for append mode without an initial fseek()?


When an existing non empty file is successfully opened by fopen() in "a+" or "ab+" mode, I should be able to read from it or write to the end without an initial call to fseek() or rewind(). Does the C Standard specify that an initial read from this file will read from the beginning of the file or should I always set the file position before reading?

The C Standard seems ambiguous as it states in 7.21.5.2 the fopen function that:

6. Opening a file with append mode (a as the first character in the mode argument) causes all subsequent writes to the file to be forced to the then current end-of-file, regardless of intervening calls to the fseek function. In some implementations, opening a binary file with append mode (b as the second or third character in the above list of mode argument values) may initially position the file position indicator for the stream beyond the last data written, because of null character padding.

On those systems where the file position indicator would point at or beyond the last data written, would an initial reading operation fail?


Solution

  • The behavior is implementation defined:

    7.21.3 Files

    1 A stream is associated with an external file (which may be a physical device) by opening a file, which may involve creating a new file. Creating an existing file causes its former contents to be discarded, if necessary. If a file can support positioning requests (such as a disk file, as opposed to a terminal), then a file position indicator associated with the stream is positioned at the start (character number zero) of the file, unless the file is opened with append mode in which case it is implementation-defined whether the file position indicator is initially positioned at the beginning or the end of the file. The file position indicator is maintained by subsequent reads, writes, and positioning requests, to facilitate an orderly progression through the file.

    So a call to rewind() or fseek(fp, 0L, SEEK_SET) is required before an initial read from the beginning of a file open for update mode/write to the end, as determined by a mode string starting with "a+" or "ab+".