Fseek Does Not Work When File Is Opened in "A" (Append) Mode

fseek does not work when file is opened in a (append) mode

When you open in append mode, the file pointer is returned to the end of file before every write. You can reposition the pointer with fseek for reading, but as soon as you call a function that writes to the file, the pointer goes back to the end of file.

Or, putting it another way, to prevent loss of data, the position of the "write pointer" overrides the position of the "read pointer". After any append, the write pointer bounces to the new EOF.

The answer at this link references the appropriate section of the C standard.

Use the "w+" mode if you would like to write to arbitrary places in file. An existing file will be overwritten.

If you would like to append to an existing file initially, but then fseek to arbitrary place, use "r+" followed by fseek(f, 0, SEEK_END).

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

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+".

When opening a file in append mode, how can I reposition the file pointer?

Look at the specification of ANSI C function fopen for "a" (APPEND) mode:
All write operations take place at the end of the file.
Your fseek will ignored.

initial value of file pointer position returned by ftell() in append mode

You ask

Why the pointer is in 0 position initially?

The only answer available at the level of generality at which you're asking as that it is a choice made by your particular implementation. The standard says:

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.

(C2011, 7.21.3/1)

Thus, implementations have the alternative of initially setting the position to the start of the file or to its end for files opened in append mode. The former is consistent with the behavior when opening the file in any other mode, and reflects the position at which the next read would occur (for append modes that permit reading, such as "a+"); the latter reflects the position at which the first write would be performed. I would favor the former, myself, since you cannot rely on the file position of a file open in append mode to reflect the position of the next write anyway (the position could always be changed via fseek().

Also is there any use of fseek in append mode?

Its primary use is not relevant to files open in append-only mode. I'm not prepared to say that it has no use, however, and I certainly wouldn't want it to error out just because such a file is passed to it. The question suggests that you have the wrong conception of the file position. Other than when a file is first opened, it is (for streams that support it) simply the location resulting from the last I/O operation on that stream, where fseek() is a bona fide I/O operation.

Of course, fseek() is perfectly sensible in its normal use for files open for both reading and appending.

fseek function is not working after fopen(argv[1], ab)

The problem is that fseek is not supposed to work when a file is opened with the "a" attribute. See here:

append: Open file for output at the end of a file. Output operations
always write data at the end of the file, expanding it. Repositioning
operations (fseek, fsetpos, rewind) are ignored. The file is created
if it does not exist.

To get round the problem, try using the "a+" attribute:

append/update: Open a file for update (both for input and output) with
all output operations writing data at the end of the file.
Repositioning operations (fseek, fsetpos, rewind) affects the next
input operations, but output operations move the position back to the
end of file. The file is created if it does not exist.

Problems getting ftell() in binary append

...so (in addition to bkVnet's answer) you must use fseek(dfile,0,SEEK_END) to seek to the end, ask ftell the position and divide that by sizeof(user1_type) to get the record id (i.e. the number of records already in the file, so plus 1 for the new record).



Related Topics



Leave a reply



Submit