Opening a File in C
- The
fopenfunction is used to open a file in C. - The file opening mode can be specified as the second argument of the
fopenfunction. - The function returns a pointer to a
FILEobject that represents the opened file, orNULLif an error occurred during file opening. - It is important to check the pointer returned by
fopento handle any file opening errors. - The access mode specifies whether the file should be opened for reading, writing, or in append mode. Additionally, it specifies whether it is a text file or a binary file.
Opening a File
The function that the C standard library provides for opening a file is the fopen function, which stands for file open. Its signature is as follows:
Function fopen
#include <stdio.h>
FILE *fopen(const char * restrict filename,
const char * restrict mode);
The fopen function requires two parameters:
filename: the name of the file to open (can include the path).mode: the file opening mode (for example, read, write, etc.).
It returns a pointer to a FILE object that represents the opened file, or NULL if an error occurred during file opening.
The first argument of the fopen function represents a string that contains the name (the path more precisely) of the file to open. The path contains all the information necessary to locate the file in the file system, including any directories or subdirectories. It can be:
- absolute: specifies the complete path from the root of the file system (for example,
/home/user/documents/file.txt). - relative: specifies a path relative to the current working directory (for example,
documents/file.txt), where by current working directory we mean the directory where the running program is located.
The filename parameter under Windows
Special attention must be paid to the filename parameter under the Windows operating system.
Under Windows, file paths use the backslash (\) as a directory separator, while under Unix/Linux the forward slash (/) is used.
However, in C language strings the backslash is used to indicate escape characters. So, for example, in a filename like this:
C:\path\file.txt
The two backslashes would be interpreted as the beginning of escape characters (non-existent by the way) \p and \f.
Therefore, if you specify an absolute or relative path in a C program intended to run on Windows, you must use the escape character \\ which represents the single backslash. For example:
FILE *file = fopen("C:\\path\\file.txt", "r");
In recent versions of Windows and Visual Studio, to overcome this problem you can use the forward slash (/) as a directory separator, which is also correctly interpreted in C language strings. For example:
FILE *file = fopen("C:/path/file.txt", "r");
The second argument represents a string that indicates the access mode, that is, it specifies which operations are intended to be performed on the file in question. An example is the "r" mode which indicates that the file must be opened in read mode. We will see the modes in detail in the next section.
We notice two fundamental details regarding the parameters of the fopen function:
-
The parameters are pointers to
charof typerestrict:This means that the two strings,
filenameandmode, must not overlap in memory. -
The
modeparameter is a pointer tochar, that is, a string and does not represent a single character. In fact, it can be composed of a sequence of characters.
The fopen function returns a pointer to a FILE object that represents the opened file, or NULL if an error occurred during file opening.
This pointer must be saved in a variable to then access it with other functions in the rest of the program. For example:
FILE *file = fopen("example.txt", "r");
Other file access functions require the pointer returned by fopen as input. We will see them in the next lessons.
Usually, when fopen fails, that is, it cannot open the file for various reasons, it returns the value NULL.
Always check the pointer returned by fopen
One should never assume that the call to fopen succeeds. It is not certain that a file can be opened for a series of reasons:
- The file might not exist;
- The user might not have permissions;
- The file might have been opened by another program.
Therefore one must always check the pointer returned by fopen before using it. For example:
FILE *file = fopen("example.txt", "r");
if (file == NULL) {
printf("Error opening file");
return 1;
}
File Access Modes
We said that the second parameter of the fopen function allows specifying the file access mode.
Through this parameter, however, not only the access mode is specified but also the file type, that is, whether the file being opened is a text file or a binary file. Therefore, access modes are divided into two groups depending on the file type.
If the file to be accessed is a text file, the mode parameter can take one of the following values:
| Value | Description | Notes |
|---|---|---|
"r" |
Opening in read mode | The file must already exist |
"w" |
Opening in write mode starting from the beginning | The file does not need to exist. If it does not exist, it is created. |
"a" |
Opening in write mode (append) starting from the end. | If the file does not exist, it is created. |
"r+" |
Opening in read and write mode from the beginning of the file | The file must already exist. |
"w+" |
Opening in read and write mode starting from the beginning of the file | If the file does not exist, it is created. If it exists, it is truncated. |
"a+" |
Opening in read and write mode starting from the end of the file | If the file does not exist, it is created. |
Conversely, if the file is a binary file, the mode parameter can take one of the following values which are similar to the previous ones but to which we add a b:
| Value | Description | Notes |
|---|---|---|
"rb" |
Opening in read mode | The file must already exist |
"wb" |
Opening in write mode starting from the beginning | The file does not need to exist. If it does not exist, it is created. |
"ab" |
Opening in write mode (append) starting from the end. | If the file does not exist, it is created. |
"r+b" or "rb+" |
Opening in read and write mode from the beginning of the file | The file must already exist. |
"w+b" or "wb+" |
Opening in read and write mode starting from the beginning of the file | If the file does not exist, it is created. If it exists, it is truncated. |
"a+b" or "ab+" |
Opening in read and write mode starting from the end of the file | If the file does not exist, it is created. |
As can be observed from the two tables above, the C standard library distinguishes file writing into two modes: writing (write) and append (write at the end or addition).
When a file is opened in write mode, normally the file is truncated, that is, if the file already existed, its content is deleted and the file is filled with new data starting from the beginning.
Conversely, if a file is opened in append mode, data is written at the end of the file preserving the old content; this obviously if the file already existed. This is why we speak of append or addition.
Hybrid read/write modes, however, require particular attention. One cannot read first and then write (or vice versa) without properly managing the position in the file. The position in the file represents the current offset from which one reads or writes. We will return to this concept in the next lessons where we will study it in detail.