Question about fscanf() behavior

G

Gary Baydo

The following program illustrates a question I have about fscanf()
behavior:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
FILE *testfile;
char s1[] = "01234567890123456789";
int c;

/* create a file and write some test data */
testfile = fopen("test.dat", "w+");
if (testfile == NULL) {
printf("Could not open file\n");
return EXIT_FAILURE;
}
fprintf(testfile, "%s", s1);

/* rewind() testfile and fputc() a character ... */
rewind(testfile);
fputc('Z', testfile);

/* ... and read-in s1 with fscanf() */
strcpy(s1, "overwriteMe");
c = fscanf(testfile, "%s", s1);

/* print the results */
printf("%d %s\n", c, s1);

fclose(testfile);

return EXIT_SUCCESS;
}

After rewinding the file and printing a character to it, I would expect
fscanf() to begin reading at position 1, but it returns EOF and leaves the
string s1 unchanged (at least with Borland's compiler on my Win XP
machine.) I've googled on this, but haven't found an answer. Neither
have I found an answer in _C A Reference Manual_, fifth edition. From
what I understand a file position indicater is maintained in the FILE
structure, but I'm not expert enough (yet) to know how to check that.
Thanks for any help.

--Gary
 
E

Eric Sosman

Gary said:
The following program illustrates a question I have about fscanf()
behavior:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
FILE *testfile;
char s1[] = "01234567890123456789";
int c;

/* create a file and write some test data */
testfile = fopen("test.dat", "w+");
if (testfile == NULL) {
printf("Could not open file\n");
return EXIT_FAILURE;
}
fprintf(testfile, "%s", s1);

Probably not the source of trouble, but something you
should be aware of: An output line is "well-formed" only if
it ends with a newline character. On some systems if you
omit the newline on the last line written, that line may
never actually be recorded in the file.
/* rewind() testfile and fputc() a character ... */
rewind(testfile);
fputc('Z', testfile);

/* ... and read-in s1 with fscanf() */
strcpy(s1, "overwriteMe");
c = fscanf(testfile, "%s", s1);

Here, though, is a real problem. When you "switch
directions" between output and input, you need to give the
I/O machinery a chance to shift gears, as it were. You
can't just do an output operation immediately followed by
input, or input immediately followed by output; you must
call one of the file-positioning functions rewind(), fseek(),
or fsetpos() in between. (When switching from output to
input, an fflush() in between will also work.) C Standard,
section 7.19.5.3, paragraph 6.
 
G

Gary Baydo

Here, though, is a real problem. When you "switch
directions" between output and input, you need to give the
I/O machinery a chance to shift gears, as it were. You
can't just do an output operation immediately followed by
input, or input immediately followed by output; you must
call one of the file-positioning functions rewind(), fseek(),
or fsetpos() in between. (When switching from output to
input, an fflush() in between will also work.) C Standard,
section 7.19.5.3, paragraph 6.

Thank you. I downloaded the C99 Rationale v5.10 and found your
reference. This requirement is not mentioned in Deitel's _C How to
Program_, fourth edition, in the chapter on "C File Processing." Nor are
a few other things I've learned in the last few minutes. Thanks again.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top