A file represents a sequence of bytes. The fopen( ) function associates a file with a stream and initializes an object of the type FILE, which contains all the information necessary to control the stream. Such information includes a pointer to the buffer used; a file position indicator , which specifies a position to access in the file; and flags to indicate error and end-of-file conditions.
Each of the functions that open filesnamely fopen( ), freopen( ), and tmpfile( )returns a pointer to a FILE object for the stream associated with the file being opened. Once you have opened a file, you can call functions to transfer data and to manipulate the stream. Such functions have a pointer to a FILE objectcommonly called a FILE pointeras one of their arguments. The FILE pointer specifies the stream on which the operation is carried out.
The I/O library also contains functions that operate on the file system, and take the name of a file as one of their parameters. These functions do not require the file to be opened first. They include the following:
Conditions that can cause the rename( ) function to fail include the following: no file exists with the old name; the program does not have the necessary access privileges; or the file is open. The rules for forming permissible filenames depend on the implementation.
13.2.1. File Position
Like the elements of a char array, each character in an ordinary file has a definite position in the file. The file position indicator in the object representing the stream determines the position of the next character to be read or written.
When you open a file for reading or writing, the file position indicator points to the beginning of the file, so that the next character accessed has the position 0. If you open the file in "append" mode, the file position indicator may point to the end of the file. Each read or write operation increases the indicator by the number of characters read from the file or written to the file. This behavior makes it simple to process the contents of a file sequentially. Random access within the file is achieved by using functions that change the file position indicator, fseek( ), fsetpos( ), and rewind( ), which are discussed in detail in "Random File Access," later in this chapter.
Of course, not all files support changing access positions. Sequential I/O devices such as terminals and printers do not, for example.
In working with files, it is generally not efficient to read or write individual characters. For this reason, a stream has a buffer in which it collects characters, which are transferred as a block to or from the file. Sometimes you don't want buffering, however. For example, after an error has occurred, you might want to write data to a file as directly as possible.
Streams are buffered in one of three ways:
You can also explicitly transfer the characters in the stream's output buffer to the associated file by calling the fflush( ) function. The buffer is also flushed when you close a stream, and normal program termination flushes the buffers of all the program's streams.
When you open an ordinary file by calling fopen( ), the new stream is fully buffered. Opening interactive devices is different, however: such device files are associated on opening with a line-buffered stream. After you have opened a file, and before you perform the first input or output operation on it, you can change the buffering mode using the setbuf( ) or setvbuf( ) function.
13.2.3. The Standard Streams
Three standard text streams are available to every C program on starting. These streams do not have to be explicitly opened. Table 13-1 lists them by the names of their respective FILE pointers.
stdin is usually associated with the keyboard, and stdout and stderr with the console display. These associations can be modified by redirection. Redirection is performed either by the program calling the freopen( ) function, or by the environment in which the program is executed.