fseek() — Change file position

Standards

Standards / Extensions C or C++ Dependencies
ISO C
POSIX.1
XPG4
XPG4.2
C99
Single UNIX Specification, Version 3 Language Environment®
both  

Format

#include <stdio.h>

int fseek(FILE *stream, long int offset, int origin);

#define _OPEN_SYS_UNLOCKED_EXT 1
#include <stdio.h>

int fseek_unlocked(FILE *stream, long int offset, int origin);

General description

The fseek() function changes the current file position associated with stream to a new location within the file. The next operation on the stream takes place at the new location. On a stream opened for update, the next operation can be either a reading or a writing operation.

The origin must be one of the following constants defined in stdio.h:
Origin
Definition
SEEK_SET
Beginning of file
SEEK_CUR
Current position of file pointer
SEEK_END
End of file

If successful, the fseek() function clears the EOF indicator, even when origin is SEEK_END, and cancels the effect of any preceding ungetc() or ungetwc() function on the same stream.

If the call to the fseek() function or the fsetpos() function is not valid, the call is treated as a flush and the ungetc characters are discarded.

Behavior for binary streams: ANSI states that binary streams use relative byte offsets for both the ftell() and fseek() functions. Under z/OS® XL C/C++, this is true except for record-oriented files that have variable length records. For these types of files, the default behavior is to use encoded offsets for the ftell() function and the fseek() function using an origin of SEEK_SET.

Encoded offsets restrict you to seeking only to those positions that are recorded by a previous ftell() function call or to position 0. If you want to use relative-byte offsets for these types of files, you can either open the file with the BYTESEEK fopen() function option or set the _EDC_BYTE_SEEK environment variable before opening.

With relative-byte offsets, you can calculate your own offsets. If the offset exceeds the EOF, your file is extended with NULLs, except for z/OS UNIX files, for which the file is only extended with NULLs if you subsequently write new data. This is true also under POSIX, using z/OS UNIX files, where the file is only extended with NULLs if you subsequently write new data.

Attempting to reposition to before the start of the file causes the fseek() function to fail.

Regardless of whether encoded or relative offsets are returned by the ftell() function, you can specify relative offsets when using SEEK_CUR and SEEK_END.

If the new position is before the start of the file, the fseek() function fails. If the relative offset is positioned beyond the EOF, the file is padded with NULLs, except in the case of POSIX, using z/OS UNIX files, where padding does not occur until a subsequent write of new data.

Behavior for text streams: For text streams, the ftell() function returns an encoded offset. When seeking with an origin of SEEK_SET, you are restricted to seeking only to 0 or to positions returned by a previous ftell() function call.

Attempting to calculate your own position is not supported, and might result in a non-valid position and the failure of the fseek() function.

When you are using SEEK_CUR or SEEK_END, the offset is a relative byte offset. Attempting to seek to before the start of the file or past the EOF results in failure.

Behavior for record I/O: For files opened for record I/O using the type=record open mode parameter, the ftell() function returns the relative record number. For the origins of SEEK_SET, SEEK_CUR, and SEEK_END, the offset is a relative record number.

Attempting to seek to before the first record or past the EOF results in failure.

Behavior for blocked I/O: For files opened for blocked I/O using the type=blocked open mode parameter, the ftell() function returns the relative block number. For the origins of SEEK_SET, SEEK_CUR, and SEEK_END, the offset is a relative block number.

Attempting to seek to before the first block or past the EOF results in failure.

Behavior for wide-oriented streams: All of the above restrictions apply for wide-oriented streams of any type.

Multivolume data sets performance: Using the fgetpos() and fsetpos() functions generally results in better repositioning performance compared to the ftell() and fseek() functions when working with multivolume data sets.

Large file support for MVS™ data sets, VSAM data sets, and z/OS UNIX files: For AMODE 31 C/C++ applications, the fseek() function accepts a signed 4-byte offset and therefore cannot be used to directly or relatively position to offsets beyond 2 GB - 1. To avoid repositioning limitations, AMODE 31 C/C++ applications should define the _LARGE_FILES feature test macro before any headers are included and replace the fseek() function with the fseeko() function. For AMODE 64 C/C++ applications, there are no restrictions on using the fseek() function with large files. The AMODE 64 version automatically accepts a signed 8-byte offset.

Usage notes

  1. Repositioning within a wide-oriented file and performing updates is strongly discouraged because it is not possible to predict if your update will overwrite part of a multibyte string or character, thereby invalidating subsequent data. For example, you could inadvertently add data that overwrites a shift-out. The following data expects the shift-out to be there, so is not valid if it is treated as if in the initial shift state. Repositioning to the end of the file and adding new data is safe.
  2. If you specify SEEK_CUR, any characters pushed back by the ungetc() or ungetwc() functions will have backed up the current position of the file pointer—which is the starting point of the seek. The seek will discard any pushed-back characters before repositioning, but the starting point will still be affected. For more information about calling the fseek() function after an ungetc() or ungetwc() function call, see ungetc() — Push character onto input stream and ungetwc() — Push a wide character onto a stream.
  3. The _EDC_COMPAT environment variable causes fseek() to ignore the effects of the ungetc() or ungetwc() functions. For more details, see the topic about environment variables in z/OS XL C/C++ Programming Guide.
  4. The fseek_unlocked() function is functionally equivalent to the fseek() function with the exception that it is not threadsafe. The fseek() function can safely be used in a multithreaded application if, and only if, it is called while the invoking thread owns the (FILE*) object, as is the case after a successful call to either the flockfile() or ftrylockfile() function.

Returned value

If successful in moving the pointer, the fseek() function returns 0.

If unsuccessful, or on devices that cannot seek, such as terminals and printers, the fseek() function returns nonzero.

Special behavior for XPG4.2: If unsuccessful, the fseek() function returns -1 and sets errno to one of the following values:
Error Code
Description
EOVERFLOW
The resulting file offset would be a value which cannot be represented correctly in an object of type long.
Note: Environment variable _EDC_EOVERFLOW can be used to control behavior of the fseek() function with respect to detecting an EOVERFLOW condition for z/OS UNIX files. By default, the fseek() function will continue to be able to position beyond a location that the ftell() function can return. When _EDC_EOVERFLOW is set to YES, the fseek() function will check if the new position can be returned by the ftell() function.
ESPIPE
The underlying file type for the stream is a PIPE or a socket.

Example

/* This example opens a file myfile.dat for reading.
   After performing input operations (not shown), it moves the file
   pointer to the beginning of the file.
 */
#include <stdio.h>

int main(void)
{
   FILE *stream;
   int result;

   if (stream = fopen("myfile.dat", "r"))
   { /* successful */

   if (fseek(stream, 0L, SEEK_SET));  /* moves pointer to   */
                                  /* the beginning of the file */
   { /* if not equal to 0
             then error ...    */
   }
   else {
       /* fseek() successful  */
   }
}

Related information