Difference between fseek(x,0L,0) and rewind(x). Why?
Adri Verhoef
a3 at earth.rivm.nl
Sat Apr 27 07:36:54 AEST 1991
I thought "rewind(fp)" was the same as "fseek(fp, 0L, 0)",
but it is not, as I will show in the program below.
The program can be compiled in several ways:
1. cc rewind_fseek.c
2. cc -DFSEEK rewind_fseek.c
3. cc -DFSEEK -DUPDATE=\"w+\" rewind_fseek.c
In case 2, the result of running a.out is:
[1] First string
[2] First string
In any other case, the result will be:
[1] First string
[2] Second string
The difference in compiling is clear: with -DFSEEK, "fseek" is used;
in any other case "rewind" is used.
before running a.out, make sure that "small_file" exists,
as opening a file with type "r+" does not create the file for you.
# ============= rewind_fseek.c ==============
sed 's/^X//' << 'SHAR_EOF' > 'rewind_fseek.c' &&
X#include <stdio.h>
X
X#define SMALL_FILE "small_file"
Xchar * string[2] = { "First string\n", "Second string\n" };
X
X#ifndef UPDATE
X#define UPDATE "r+"
X#endif
X
Xmain()
X{
X FILE * Cfpwr = fopen(SMALL_FILE, UPDATE);
X FILE * Cfprd = fopen(SMALL_FILE, "r");
X char buf[BUFSIZ];
X int i;
X
X if (Cfprd == NULL || Cfpwr == NULL) (void) perror(SMALL_FILE);
X else
X
X for (i=0; i<2; i++) {
X rewind(Cfpwr);
X (void) fprintf(Cfpwr, string[i]);
X (void) fflush(Cfpwr);
X#ifdef FSEEK
X (void) fseek(Cfprd, 0L, 0); /* There is a difference */
X#else /* REWIND */ /* between defining FSEEK */
X rewind(Cfprd); /* and defining REWIND. */
X#endif /* REWIND */
X if (fgets(buf, BUFSIZ, Cfprd) == NULL) {
X (void) perror("fgets");
X continue;
X }
X (void) printf("[%d] %s", i+1, buf);
X }
X return 0;
X}
SHAR_EOF
true || echo 'restore of rewind_fseek.c failed'
touch small_file
exit 0
Note that "small_file" must exist, when using "r+" for updating a file.
In the manual it is stated, that:
When a file is opened for update, both input and output may be
done on the resulting _s_t_r_e_a_m. However, output may not be
directly followed by input without an intervening _f_s_e_e_k or
_r_e_w_i_n_d, and input may not be directly followed by output without
an intervening _f_s_e_e_k, _r_e_w_i_n_d, or an input operation which
encounters end-of-file.
This is not the case in the program above, because two different file
pointers to the same file are being used; but why the odd behaviour, i.e.
Why is there a difference between using fseek and rewind, or
rather, why does rewind(x) do what fseek(x, 0L, 0) doesn't ?
[As shown above.]
As a side note, if I define UPDATE to be "w+", everything works.
(But I don't want to truncate the file in my application.)
I have tried this on Ultrix 4.1 and on SunOS 4.1 with the same result.
--
Adri (a3 at rivm.nl) - Postmaster, NewsAdmin, SysAdmin, you name it...
More information about the Comp.lang.c
mailing list