You can use the two functions in this section, fread and
fwrite, to read and write text in blocks of fixed size, rather
than by line or character. You can also use these two functions to read
and write blocks of binary data. This feature is useful if you want to
read and write data in the same format used by your program. For
example, you can store an entire multidimensional array of
floating-point variables in a file with the fwrite command, then
read it back in directly later with the fread command, without
any loss of precision caused by converting the floats to strings for use
with the fprintf function, for example. (The main drawback to
using binary files rather than formatted ASCII text files is that you
cannot easily read and edit the files you create with a text editor.)
For example, to write an array called my_array, containing
object_count data objects (such as integers), each of size
object_size, to the stream my_stream, you might use the
following line of code:
Here is a short table to help you remember the directions in which
fwrite and fread work.
fwrite
from an array, to a file
fread
from a file, to an array
The fwrite function takes four parameters. The first parameter
to fwrite is a void pointer (void *) to an array that
contains the data that will be written to the file. The second
parameter is a variable of type size_t specifying the size of
each object to be written, and the third parameter, also of type
size_t, specifies the number of those objects that are to be
written. The final parameter is the stream to be written to (type
FILE *). If the value returned by fopen does not match
the third parameter passed (that is, the number of objects to be
written), then there was an error.
Like fwrite, the fread function takes four parameters.
Its first parameter is a void pointer to the array that will be written
to. Its second parameter, of type size_t, specifies how large
each object to be read is, and its third parameter, of type
size_t, specifies how many of each object is to be read. The
last parameter is simply the stream to read from. Again, if the return
value of this function does not match the third parameter, which
specifies how many object were to be read, there was an error.
Here is an example that creates an array and fills it with multiples of 2,
prints it out, writes the array's data to a file with fwrite, zeroes the
array and prints it out, reads the data from the file back into the array with
fread, then prints the array out again so you can compare its data
with the first set of data.
#include <stdio.h>
int main()
{
int row, column;
FILE *my_stream;
int close_error;
char my_filename[] = "my_numbers.dat";
size_t object_size = sizeof(int);
size_t object_count = 25;
size_t op_return;
int my_array[5][5] =
{
2, 4, 6, 8, 10,
12, 14, 16, 18, 20,
22, 24, 26, 28, 30,
32, 34, 36, 38, 40,
42, 44, 46, 48, 50
};
printf ("Initial values of array:\n");
for (row = 0; row <= 4; row++)
{
for (column = 0; column <=4; column++)
{
printf ("%d ", my_array[row][column]);
}
printf ("\n");
}
my_stream = fopen (my_filename, "w");
op_return = fwrite (&my_array, object_size, object_count, my_stream);
if (op_return != object_count)
{
printf ("Error writing data to file.\n");
}
else
{
printf ("Successfully wrote data to file.\n");
}
/* Close stream; skip error-checking for brevity of example */
fclose (my_stream);
printf ("Zeroing array...\n");
for (row = 0; row <= 4; row++)
{
for (column = 0; column <=4; column++)
{
my_array[row][column] = 0;
printf ("%d ", my_array[row][column]);
}
printf ("\n");
}
printf ("Now reading data back in...\n");
my_stream = fopen (my_filename, "r");
op_return = fread (&my_array, object_size, object_count, my_stream);
if (op_return != object_count)
{
printf ("Error reading data from file.\n");
}
else
{
printf ("Successfully read data from file.\n");
}
for (row = 0; row <= 4; row++)
{
for (column = 0; column <=4; column++)
{
printf ("%d ", my_array[row][column]);
}
printf ("\n");
}
/* Close stream; skip error-checking for brevity of example */
fclose (my_stream);
return 0;
}
If all goes well, the code example above will produce the following output:
If you attempt to view the file my_numbers.dat produced by the
program above with a GNU command such as more numbers.dat, you
will see only garbage, because the information is stored in binary
format, not readable by humans. After attempting to view this binary
file, your terminal may continue to show only garbage and you may have
to reset it. You may be able to do this with a menu option (if you are
running gnome-terminal, for example), or you may have to type
reset blindly.