In C, you can perform read/write operations in the following ways:
Read or write one character (or byte) at a time, with functions
like fgetc
and fputc
.
Read or write one line of text (that is, one character line) at a time,
with functions like fgets
and fputs
.
Read or write one block of characters (or bytes) at a time, with
fread
and fwrite
.
In this course we are going to focus in the last way, block reading and writing, which is quite useful both for text and binary files.
The syntax for the fread
function is:
#include <stdio.h> size_t fread(void *ptr, size_t size, size_t n, FILE *stream);
Here ptr
is an array in which the data is stored.
size
indicates the size of each array element.
n
specifies the number of elements to read.
stream
is a file pointer that is associated with the opened file
for reading.
size_t
is a type defined in the header file
stdio.h
.
The fread
function returns the number of elements that are
actually read during the attempt or an EOF if it is the end of the file.
The fread
function does not distinguish between
end-of-file and another type of error so, if
fread
does not return the expected result,
you must use feof
and ferror
functions to determine what
exactly happened (we will see it in a moment).
The syntax for the fwrite
function is:
#include <stdio.h> size_t fwrite(const void *ptr, size_t size, size_t n, FILE *stream);
ptr
references the array that contains the data to be written
to an opened file pointed to by the file pointer stream
.
size
indicates the size of each element in the array.
n
specifies the number of elements to be written.
The function returns the number of elements actually written; therefore,
if no error has occurred, the value returned by fwrite
should equal the third argument in the function.
The return value may be less than the specified value if an error occurs.
As we have seen before, we have the feof
function to
determine when the end of a file is encountered.
#include <stdio.h> int feof(FILE *stream);
This function returns 0
if the end of the file has not been
reached; otherwise, it returns a nonzero integer.
Finally, we have the function ferror
to know if there
were a mistake in a read/write operation. It returns 0
if
no error has occurred; otherwise, it returns a nonzero integer.
#include <stdio.h> int ferror(FILE *stream);
The following program writes an array of numbers and then reads them one by one to calculate their sum.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | #include <stdio.h> #define SIZE 6 int main(void) { FILE *file; int numbers[SIZE] = {20, 20, 20, 20, 20, 20}; char file_name[] = "numbers.bin"; // This variable will store the result of writing/reading size_t result; /* Opening the file for writing*/ file = fopen(file_name, "w"); if (file == NULL) { printf("Error when opening file for writing.\n"); return -1; } // Writing a block of data result = fwrite(numbers, sizeof(int), SIZE, file); if (result!=SIZE) { printf("The %d numbers have not been written.\n", SIZE); } if (fclose(file)!=0) { printf("Error when closing file.\n"); return -1; } /* Open for reading */ int sum = 0; file = fopen(file_name, "r"); if (file == NULL) { printf("Error when opening file for reading.\n"); return -1; } // Reading number by number, not in block. int num; while (!feof(file)) { result = fread(&num, sizeof(int), 1, file); if (result != 1) { break; } sum = sum + num; } if (ferror(file)!=0) { printf("An error has occurred while reading.\n"); } else { printf("The sum of numbers is: %d\n.",sum); } if (fclose(file)!=0) { printf("Error when closing file.\n"); return -1; } return 0; } |
We know the array size and we can write the whole block of 6 integers. In case the number of elements were unknown, we would have to write one by one.
In line 47, break
sentence is used to exit the reading loop,
because an error or end of file has occurred and, as a consequence,
no further operation is needed inside the loop.
When exit the loop, the program checks what really has happened, in order
to advise the user.