Reputation: 37
I have a question about I/O in C language, how can I make a difference to know if the lecture of my file has ended or if the data can't be read (or has a problem) as in the both cases, fscanf returns EOF ?
Upvotes: 1
Views: 829
Reputation: 23832
As per fscanf()
return value:
§ 7.21.6.2 - 16 - The
fscanf
function returns the value of the macroEOF
if an input failure occurs before the first conversion (if any) has completed. Otherwise, the function returns the number of input items assigned, which can be fewer than provided for, or even zero, in the event of an early matching failure.
EOF
is a macro with the value of -1
, by itself it's not distinguishable as for the reasons why it occurs.
For this distinction § 7.21.6.2 - 19 recommends the use of feof()
for end-of-file and ferror()
for I/O error:
EXAMPLE 3 To accept repeatedly from
stdin
a quantity, a unit of measure, and an item name:#include<stdio.h> /*...*/ int count; floatquant; charunits[21], item[21]; do { count = fscanf(stdin, "%f%20sof%20s", &quant, units, item); fscanf(stdin,"%*[^\n]"); } while(!feof(stdin) && !ferror(stdin));
My usual approach when reading formated input, is to check the inputed values. For a sample input of 2 integers you can do something like:
int a, b;
FILE* file;
//open file to read
while(fscanf(file, "%d %d", &a, &b) == 2){ //read each 2 integers in the file, stop when condition fails, i.e. there are nothing else to read or the read input is not an integer
//...handle inputs
}
This kind of read is safe and addresses all failure scenarios since it works for bad input and for "end of file".
Upvotes: 1
Reputation: 15082
Don´t rely only on the return value of fscanf()
, rely beside this one on feof()
and ferror()
after the call to fscanf()
:
FILE* file;
if((file == fopen("file.txt","r")) == NULL)
{
fprintf(stderr, "File could not be opened!");
return EXIT_FAILURE;
}
char buf;
/******************************************************************************/
while(fscanf(file,"%c",buf) == 1) { // checks if an error was happen, else
// iterate to catching characters.
/* handling of read character */
}
if(ferror(file)) // checks if an I/O error occurred.
{
// I/O error handling
fprintf(stderr,"Input/Output error at reading file!");
clearerr(file);
// Further actions
}
else if(feof(file)) // checks if the end of the file is reached.
{
// end of file handling
fprintf(stderr,"Reached End of File!");
clearerr(file);
// Further actions
}
/******************************************************************************/
if(fclose(file) != 0)
{
fprintf(stderr, "File could not be closed properly!");
return EXIT_FAILURE;
}
Upvotes: 3