Reading and Writing Files 145
This is wrong. If fptr is NULL, then fopen fails to open the file. If the file is not open,
then it cannot be closed. The documentation of fclose clearly says:
The behaviour of fclose() is undefined if the stream parameter is an
illegal pointer, or is a descriptor already passed to a previous
invocation of fclose().
Thus, fclose(NULL) is bad, since it results in unpredictable behavior. Also, note that
it is an error to close the same file pointer twice.
What is stored at the heap memory pointed by fptr? The following uses gdb to show
the contents at the memory address pointed by fptr.
(gdb) print * fptr
$2 = {_flags = -72539000, _IO_read_ptr = 0x0, _IO_read_end = 0x0,
_IO_read_base = 0x0, _IO_write_base = 0x0, _IO_write_ptr = 0x0,
_IO_write_end = 0x0, _IO_buf_base = 0x0, _IO_buf_end = 0x0,
_IO_save_base = 0x0, _IO_backup_base = 0x0, _IO_save_end = 0x0,
_markers = 0x0, _chain = 0x7ffff7dd4180, _fileno = 3, _flags2 = 0,
_old_offset = 0, _cur_column = 0, _vtable_offset = 0 ’ 00’,
_shortbuf = "", _lock = 0x6020f0, _offset = -1, __pad1 = 0x0, __pad2
= 0x602100, __pad3 = 0x0, __pad4 = 0x0, __pad5 = 0, _mode = 0,
_unused2 = ’ 00’ <repeats 19 times>}
As we can see, the data that the FILE * points to is complicated. Fortunately, we do
not need to know the details since they are purely internal to the C library, and should not
be modified or examined directly.
10.2.2 Reading Integers: fscanf(... %d...)
In addition to fgetc, C provides many functions for reading data from a file. One of
them is fscanf. It is very similar to scanf, except that it requires one more argument. The
first argument is a FILE pointer. The following program adds the numbers in a file.
// fscanf . c1
#in clude < stdio .h >2
#in clude < stdlib .h >3
int main ( i n t argc , char * argv [])4
{5
FILE * fptr ;6
int val ;7
int sum = 0;8
i f ( argc < 2)9
{10
printf (" Need to provide the file ’s name . n") ;11
return EXIT _FAILUR E ;12
}13
fptr = fopen ( argv [1] , " r") ;14
i f ( fptr == NULL )15
{16
printf (" fopen fail . n") ;17
return EXIT _FAILUR E ;18
}19