a3@earth.rivm.nl (Adri Verhoef) (04/27/91)
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@rivm.nl) - Postmaster, NewsAdmin, SysAdmin, you name it...