The Basics of Disk File I/O
Now let's focus on how to open and close a disk data file and how to interpret error messages returned by I/O functions.
Pointers of FILE
The FILE structure is the file control structure defined in the header file stdio.h. A pointer of type FILE is called a file pointer, which references a disk file. A file pointer is used by a stream to conduct the operation of the I/O functions. For instance, the following defines a file pointer called fptr:
FILE *fptr;
In the FILE structure there is a member, called the file position indicator, that points to the position in a file where data will be read from or written to. You'll learn how to move the file position indicator in the next lesson.
Opening a File
The C I/O function fopen() gives you the ability to open a file and associate a stream to the opened file. You need to specify the way to open a file and the filename with the fopen() function.
The syntax for the fopen() function is
#include <stdio.h>
FILE *fopen(const char *filename, const char *mode);
Here filename is a char pointer that references a string of a filename. The filename is given to the file that is about to be opened by the fopen() function. mode points to another string that specifies the way to open the file. The fopen() function returns a pointer of type FILE. If an error occurs during the procedure to open a file, the fopen() function returns a null pointer.
The following list shows the possible ways to open a file by various strings of modes:
"r" opens an existing text file for reading.
"w" creates a text file for writing.
"a" opens an existing text file for appending.
"r+" opens an existing text file for reading or writing.
"w+" creates a text file for reading or writing.
"a+" opens or creates a text file for appending.
"rb" opens an existing binary file for reading.
"wb" creates a binary file for writing.
"ab" opens an existing binary file for appending.
"r+b" opens an existing binary file for reading or writing.
"w+b" creates a binary file for reading or writing.
"a+b" opens or creates a binary file for appending.
Note that you might see people use the mode "rb+" instead of "r+b". These two strings are equivalent. Similarly, "wb+" is the same as "w+b"; "ab+" is equivalent to "a+b".
The following statements try to open a file called test.txt:
FILE *fptr;
if ((fptr = fopen("test.txt", "r")) == NULL){
printf("Cannot open test.txt file.\n");
exit(1);
}
Here "r" is used to indicate that a text file is about to be opened for reading only. If an error occurs when the fopen() function tries to open the file, the function returns a null pointer. Then an error message is printed out by the printf() function and the program is aborted by calling the exit() function with a nonzero value.
Closing a File
After a disk file is read, written, or appended with some new data, you have to disassociate the file from a specified stream by calling the fclose() function.
The syntax for the fclose() function is
#include <stdio.h>
int fclose(FILE *stream);
Here stream is a file pointer that is associated with a stream to the opened file. If fclose() closes a file successfully, it returns 0. Otherwise, the function returns EOF. Normally, the fclose() function fails only when the disk is removed before the function is called or there is no more space left on the disk.
Since all high-level I/O operations are buffered, the fclose() function flushes data left in the buffer to ensure that no data will be lost before it disassociates a specified stream with the opened file.
Note that a file that is opened and associated with a stream has to be closed after the I/O operation. Otherwise, the data saved in the file may be lost; some unpredictable errors might occur during the execution of your program.
The program in listing 21.1 shows you how to open and close a text file and how to check the returned file pointer value as well.
TYPE
Listing 21.1. Opening and closing a text file.
1: /* 21L01.c: Opening and closing a file */
2: #include <stdio.h>
3:
4: enum {SUCCESS, FAIL};
5:
6: main(void)
7: {
8: FILE *fptr;
9: char filename[]= "haiku.txt";
10: int reval = SUCCESS;
11:
12: if ((fptr = fopen(filename, "r")) == NULL){
13: printf("Cannot open %s.\n", filename);
14: reval = FAIL;
15: } else {
16: printf("The value of fptr: 0x%p\n", fptr);
17: printf("Ready to close the file.");
18: fclose(fptr);
19: }
20:
21: return reval;
22: }
OUTPUT
The following output shows on my screen after running the executable 21L01.exe of the program in Listing 21.1. (Note that the value of the fptr is likely to be different on your machine. That's okay.)
ANALYSIS
C:\app>21L01
The value of fptr: 0x013E
Ready to close the file.
C:\app>
The purpose of the program in Listing 21.1 is to show you how to open a text file. From the expression in line 12, you can see that the fopen() function tries to open a text file with the name contained by the character array filename for reading. The filename array is defined and initialized with the name haiku.txt in line 9.
If an error occurs when you try to open the text file, the fopen() function returns a null pointer. Line 13 then prints a warning message, and line 14 assigns the value represented by the enum name FAIL to the int variable reval. From the declaration of the enum data type in line 4, we know that the value of FAIL is 1.
If, however, the fopen() function opens the text file successfully, the statement in line 16 prints the value contained by the file pointer fptr. Line 17 tells the user that the program is about to close the file, and line 18 then closes the file by calling the fclose() file.
In line 21, the return statement returns the value of reval that contains 0 if the text file has been opened successfully, or 1 otherwise.
From the output shown on my screen, I see that the value held by the file pointer fptr is 0x013E after the text file is opened.
- 12 views