fseek [ HP C/iX Library Reference Manual ] MPE/iX 5.0 Documentation
HP C/iX Library Reference Manual
fseek
Positions the next I/O operation on an open stream to a new position
relative to the current position.
Syntax
#include <stdio.h>
int fseek (FILE *stream, long int offset, int ptrname);
Parameters
stream A pointer to an open stream.
offset The number of bytes to skip over. The offset parameter can
be negative or positive, indicating backward or forward
movement in the file, respectively.
ptrname The reference point in the file from which offset bytes are
measured.
Return Values
0 Success.
-1 An error occurred, and errno is set to indicate the error
condition.
Description
The fseek function sets the file position indicator for the stream
pointed to by stream.
For a binary stream, the new position, measured in characters from the
beginning of the file, is obtained by adding offset to the position
specified by whence. The specified position is:
* The beginning of the file if whence is SEEK_SET.
* The current value of the file position indicator if whence is
SEEK_CUR.
* The end-of-file if whence is SEEK_END.
For a text stream, either offset is zero, or offset is a value returned
from a previous call to ftell() on the same stream, and whence is
SEEK_SET.
A successful call to fseek() clears the end-of-file indicator for the
stream and undoes any effect of ungetc() on the same stream. After an
fseek() call, the next operation on an update stream can be either input
or output.
[REV BEG]
NOTE If linking with the POSIX/iX library, fseek() allows the file
offset to be set beyond the end of the existing data in the file.
If data is written at this point, the gap between the old and new
end-of-file is zero filled. However, fseek() cannot by itself
extend the size of the file.
[REV END]
Example
The following program uses the ftell() and fseek() functions. The
program prints each line of an n-line file in this order: line 1, line
n, line 2, line n-1, line 3, and so on.
#include <stdio.h>
main(argc, argv)
int argc;
char *argv[ ];
{
char line[256];
int newlines;
long front, rear, ftell();
FILE *fp;
front = 0;
rear = 0;
if(argc < 2) {
fprintf(stderr, "Usage: print filename\n");
exit(1);
}
fp = fopen(argv[1], "r");
if(fp == NULL) {
fprintf(stderr, "Can't open %s.\n", argv[1]);
exit(1);
}
newlines = countnl(fp) % 2;
fseek(fp, 0, 2);
rear = ftell(fp);
while(front < rear) {
fseek(fp, front, 0);
fgets(line, 256, fp);
fputs(line, stdout);
front = ftell(fp);
findnl(fp, rear);
rear = ftell(fp);
if(newlines == 1) {
if(rear <= front)
break;
}
fgets(line, 256, fp);
fputs(line, stdout);
}
exit(0);
}
countnl(fp)
FILE *fp;
{
char c;
int count = 0;
while((c = getc(fp)) != EOF) {
if(c == '\n')
count++;
}
rewind(fp);
return(count);
}
findnl(fp, offset)
FILE *fp;
long offset;
{
char c;
fseek(fp, (offset-2), 0);
while((c = getc(fp)) != '\n') {
fseek(fp, -2, 1);
}
}
This program uses the ftell() and fseek() functions to print lines from a
file starting at the beginning and the end of the file, and converging
toward the center. The countnl() function counts the number of lines in
the file so the program can decide whether or not to print a line in the
final loop to prevent the middle line being printed twice in files with
an odd number of lines. The findnl() function searches backwards in the
file for the next newline character. When found, this positions the next
I/O operation such that fgets() gets the next line back from the end of
the file.
All three types of seeks are represented in this program. The first
fseek() of the program is done relative to the end of the file. All
other fseek() operations in the main program are done relative to the
beginning of the file. Finally, findnl() contains an fseek() that is
relative to the current position.
The example located in the fread() function description uses a structure
that described each employee, as shown below:
struct emp {
char name[40]; /* name */
char job[40]; /* job title */
long salary; /* salary */
char hire[6]; /* hire date */
char curve[2]; /* pay curve */
int rank; /* percentile ranking */
}
This function reads the data for 400 employees all at once. Suppose you
want the program to be selective, so that you can specify by employee
number (1 through 400) which employee's information you want. The
following program fragment shows how to use fseek to do this:
:
int empno, bytes;
long total;
FILE *data;
struct emp empinfo;
/* check for usage error and open data file */
:
sscanf(argv[1], "%d", &empno);
bytes = sizeof(empinfo);
total = (empno - 1) * bytes;
fseek(data, total, 0);
fread((char *)&empinfo, sizeof(empinfo), 1, data);
/* print out desired information */
:
exit(0);
}
In this program, argv[1] contains, using a command-line argument, the
employee number about whom information is desired. The employee number
is converted to integer form using sscanf. The number of bytes per
employee structure is obtained using sizeof, and is stored in bytes. The
total number of bytes to skip in the data file is found by multiplying
the employee number (minus one) times the number of bytes per employee
structure. This is stored in total. Then, fseek() is used to seek past
the specified number of bytes, relative to the beginning of the data
file. This leaves the next I/O operation positioned at the start of the
specified employee's information. The information is read using fread().
See Also
ftell(), rewind(), ANSI C 4.9.9.2, POSIX.1 8.1
MPE/iX 5.0 Documentation