146 Intermediate C Programming
printf (" The name of the file is %s . n ", argv [1]) ;20
while ( fscanf ( fptr , " %d" , & val ) == 1)21
{22
printf (" %d ", val ) ;23
sum += val ;24
}25
fclose ( fptr );26
printf (" nThe sum is %d .n " , sum );27
return EXIT _SUCCES S ;28
}29
This program keeps reading until no more integers can be read. Each call of fscanf
function returns the number of value(s) successfully read. We can use fscanf to attempt to
read multiple values at once. This example reads only one integer at a time. The returned
value will be either 1 if a single value is successfully read, or 0 if no value can be successfully
read. This means to keep reading as long as fscanf can still find another integer in the
file. A common mistake is thinking that fscanf returns the value read from this file. This
is wrong; instead, fscanf returns how many values are read from the file. The pattern
"%d" indicates that we only attempt to read one integer. If only one integer is read, fscanf
returns 1, regardless of the integer’s value. Every time fscanf is called, the file stream
moves forward and eventually reaches the end of the file.
Suppose we have a file called intfile that stores some integers:
4 7 8
32
71
6 -2 5 8
Below is the output when we run the program with intfile as the command-line argument:
The name of the file is intfile.
4 7 8 32 71 6 -2 5 8
The sum is 139.
Compared with fgetc, fscanf has several advantages:
• When using %d, fscanf skips characters (such as space and new line ’n’) that are
not digits.
• If two integers are separated by characters that are not digits, fscanf separates the
two integers automatically.
• When fgetc reads the first character, it is not the integer 4, but instead the character
’4’ because it is treated as a character. A character can be converted to an integer
using the ASCII table. Type
$ man ascii
into the terminal to see an ASCII table, and note that the character ’4’ has the decimal
value 52.
• If a number is greater than 9, the number has two or more digits. Using fgetc, only
one digit is read at a time. If the number is 123, then we need to call fgetc three times
in order to get the three digits. Moreover, we need to change the three characters ’1’,
’2’, and ’3’ (ASCII values 49, 50, 51) to the integer value 123 (one hundred and twenty
three). This is done by fscanf automatically.
Due to the above reasons, if a program reads integers from a file, fscanf is a better
choice than fgetc.