Go to the previous, next section.

Input/Output on Streams

This chapter describes the functions for creating streams and performing input and output operations on them. As discussed in section Input/Output Overview, a stream is a fairly abstract, high-level concept representing a communications channel to a file, device, or process.

Streams

For historical reasons, the type of the C data structure that represents a stream is called FILE rather than "stream". Since most of the library functions deal with objects of type FILE *, sometimes the term file pointer is also used to mean "stream". This leads to unfortunate confusion over terminology in many books on C. This manual, however, is careful to use the terms "file" and "stream" only in the technical sense.

The FILE type is declared in the header file `stdio.h'.

Data Type: FILE

This is the data type is used to represent stream objects. A FILE object holds all of the internal state information about the connection to the associated file, including such things as the file position indicator and buffering information. Each stream also has error and end-of-file status indicators that can be tested with the ferror and feof functions; see section End-Of-File and Errors.

FILE objects are allocated and managed internally by the input/output library functions. Don't try to create your own objects of type FILE; let the library do it. Your programs should deal only with pointers to these objects (that is, FILE * values) rather than the objects themselves.

Standard Streams

When the main function of your program is invoked, it already has three predefined streams open and available for use. These represent the "standard" input and output channels that have been established for the process.

These streams are declared in the header file `stdio.h'.

Macro: FILE * stdin

The standard input stream, which is the normal source of input for the program.

Macro: FILE * stdout

The standard output stream, which is used for normal output from the program.

Macro: FILE * stderr

The standard error stream, which is used for error messages and diagnostics issued by the program.

In the GNU system, you can specify what files or processes correspond to these streams using the pipe and redirection facilities provided by the shell. (The primitives shells use to implement these facilities are described in section File System Interface.) Most other operating systems provide similar mechanisms, but the details of how to use them can vary.

It is probably not a good idea to close any of the standard streams. But you can use freopen to get te effect of closing one and reopening it. See section Opening Streams.

Opening Streams

Opening a file with the fopen function creates a new stream and establishes a connection between the stream and a file. This may involve creating a new file.

Everything described in this section is declared in the header file `stdio.h'.

Function: FILE * fopen (const char *filename, const char *opentype)

The fopen function opens a stream for I/O to the file filename, and returns a pointer to the stream.

The opentype argument is a string that controls how the file is opened and specifies attributes of the resulting stream. It must begin with one of the following sequences of characters:

`r'
Open an existing file for reading only.

`w'
Open the file for writing only. If the file already exists, it is truncated to zero length. Otherwise a new file is created.

`a'
Open file for append access; that is, writing at the end of file only. If the file already exists, its initial contents are unchanged and output to the stream is appended to the end of the file. Otherwise, a new, empty file is created.

`r+'
Open existing file for both reading and writing. The initial contents of the file are unchanged and the initial file position is at the beginning of the file.

`w+'
Open file for both reading and writing. If the file already exists, it is truncated to zero length. Otherwise, a new file is created.

`a+'
Open or create file for both reading and appending. If the file exists, its initial contents are unchanged. Otherwise, a new file is created. The initial file position for reading might be at either the beginning or end of the file, but output is always appended to the end of the file.

As you can see, `+' requests a stream that can do both input and output. When using such a stream, you must call fflush (see section Stream Buffering) or a file positioning function such as fseek (see section File Positioning) when switching from reading to writing or vice versa. Otherwise, internal buffers might not be emptied properly.

The GNU C library defines one additional character for use in opentype: the character `x' insists on creating a new file--if a file filename already exists, fopen fails rather than opening it. This is equivalent to the O_EXCL option to the open function (see section File Status Flags).

The character `b' in opentype has a standard meaning; it requests a binary stream rather than a text stream. But this makes no difference in POSIX systems (including the GNU system). If both `+' and `b' are specified, they can appear in either order. See section Text and Binary Streams.

Any other characters in opentype are simply ignored. They may be meaningful in other systems.

If the open fails, fopen returns a null pointer.

You can have multiple streams (or file descriptors) pointing to the same file open at the same time. If you do only input, this works straightforwardly, but you must be careful if any output streams are included. See section Precautions for Mixing Streams and Descriptors. This is equally true whether the streams are in one program (not usual) or in several programs (which can easily happen). It may be advantageous to use the file locking facilities to avoid simultaneous access. See section File Locks.

Macro: int FOPEN_MAX

The value of this macro is an integer constant expression that represents the minimum number of streams that the implementation guarantees can be open simultaneously. The value of this constant is at least eight, which includes the three standard streams stdin, stdout, and stderr.

Function: FILE * freopen (const char *filename, const char *opentype, FILE *stream)

This function is like a combination of fclose and fopen. It first closes the stream referred to by stream, ignoring any errors that are detected in the process. (Because errors are ignored, you should not use freopen on an output stream if you have actually done any output using the stream.) Then the file named by filename is opened with mode opentype as for fopen, and associated with the same stream object stream.

If the operation fails, a null pointer is returned; otherwise, freopen returns stream.

The main use of freopen is to connect a standard stream such as stdir with a file of your own choice. This is useful in programs in which use of a standard stream for certain purposes is hard-coded.

Closing Streams

When a stream is closed with fclose, the connection between the stream and the file is cancelled. After you have closed a stream, you cannot perform any additional operations on it any more.

Function: int fclose (FILE *stream)

This function causes stream to be closed and the connection to the corresponding file to be broken. Any buffered output is written and any buffered input is discarded. The fclose function returns a value of 0 if the file was closed successfully, and EOF if an error was detected.

It is important to check for errors when you call fclose to close an output stream, because real, everyday errors can be detected at this time. For example, when fclose writes the remaining buffered output, it might get an error because the disk is full. Even if you you know the buffer is empty, errors can still occur when closing a file if you are using NFS.

The function fclose is declared in `stdio.h'.

If the main function to your program returns, or if you call the exit function (see section Normal Termination), all open streams are automatically closed properly. If your program terminates in any other manner, such as by calling the abort function (see section Aborting a Program) or from a fatal signal (see section Signal Handling), open streams might not be closed properly. Buffered output may not be flushed and files may not be complete. For more information on buffering of streams, see section Stream Buffering.

Simple Output by Characters or Lines

This section describes functions for performing character- and line-oriented output. Largely for historical compatibility, there are several variants of these functions, but as a matter of style (and for simplicity!) we suggest you stick with using fputc and fputs, and perhaps putc and putchar.

These functions are declared in the header file `stdio.h'.

Function: int fputc (int c, FILE *stream)

The fputc function converts the character c to type unsigned char, and writes it to the stream stream. EOF is returned if a write error occurs; otherwise the character c is returned.

Function: int putc (int c, FILE *stream)

This is just like fputc, except that most systems implement it as a macro, making it faster. One consequence is that it may evaluate the stream argument more than once.

Function: int putchar (int c)

The putchar function is equivalent to fputc with stdout as the value of the stream argument.

Function: int fputs (const char *s, FILE *stream)

The function fputs writes the string s to the stream stream. The terminating null character is not written. This function does not add a newline character, either. It outputs only the chars in the string.

This function returns EOF if a write error occurs, and otherwise a non-negative value.

For example:

fputs ("Are ", stdout);
fputs ("you ", stdout);
fputs ("hungry?\n", stdout);

outputs the text `Are you hungry?' followed by a newline.

Function: int puts (const char *s)

The puts function writes the string s to the stream stdout followed by a newline. The terminating null character of the string is not written.

Function: int putw (int w, FILE *stream)

This function writes the word w (that is, an int) to stream. It is provided for compatibility with SVID, but we recommend you use fwrite instead (see section Block Input/Output).

Character Input

This section describes functions for performing character- and line-oriented input. Again, there are several variants of these functions, some of which are considered obsolete stylistically. It's suggested that you stick with fgetc, getline, and maybe getc, getchar and fgets.

These functions are declared in the header file `stdio.h'.

Function: int fgetc (FILE *stream)

This function reads the next character as an unsigned char from the stream stream and returns its value, converted to an int. If an end-of-file condition or read error occurs, EOF is returned instead.

Function: int getc (FILE *stream)

This is just like fgetc, except that it is permissible (and typical) for it to be implemented as a macro that evaluates the stream argument more than once.

Function: int getchar (void)

The getchar function is equivalent to fgetc with stdin as the value of the stream argument.

Here is an example of a function that does input using fgetc. It would work just as well using getc instead, or using getchar () instead of fgetc (stdin).

int
y_or_n_p (const char *question)
{
  fputs (question, stdout);
  while (1) {
    int c, answer;
    /* Write a space to separate answer from question. */
    fputc (' ', stdout);
    /* Read the first character of the line.
       This should be the answer character, but might not be. */
    c = tolower (fgetc (stdin));
    answer = c;
    /* Discard rest of input line. */
    while (c != '\n')
      c = fgetc (stdin);
    /* Obey the answer if it was valid. */
    if (answer == 'y')
      return 1;
    if (answer == 'n')
      return 0;
    /* Answer was invalid: ask for valid answer. */
    fputs ("Please answer y or n:", stdout);
  }
}

Function: int getw (FILE *stream)

This function reads a word (that is, an int) from stream. It's provided for compatibility with SVID. We recommend you use fread instead (see section Block Input/Output).

Line-Oriented Input

Since many programs interpret input on the basis of lines, it's convenient to have functions to read a line of text from a stream.

Standard C has functions to do this, but they aren't very safe: null characters and even (for gets) long lines can confuse them. So the GNU library provides the nonstandard getline function that makes it easy to read lines reliably.

Another GNU extension, getdelim, generalizes getline. It reads a delimited record, defined as everything through the next occurrence of a specified delimeter character.

All these functions are declared in `stdio.h'.

Function: ssize_t getline (char **lineptr, size_t *n, FILE *stream)

This function reads an entire line from stream, storing the text (including the newline and a terminating null character) in a buffer and storing the buffer address in *lineptr.

Before calling getline, you should place in *lineptr the address of a buffer *n bytes long. If this buffer is long enough to hold the line, getline stores the line in this buffer. Otherwise, getline makes the buffer bigger using realloc, storing the new buffer address back in *lineptr and the increased size back in *n.

In either case, when getline returns, *lineptr is a char * which points to the text of the line.

When getline is successful, it returns the number of characters read (including the newline, but not including the terminating null). This value enables you to distinguish null characters that are part of the line from the null character inserted as a terminator.

This function is a GNU extension, but it is the recommended way to read lines from a stream. The alternative standard functions are unreliable.

If an error occurs or end of file is reached, getline returns -1.

Function: ssize_t getdelim (char **lineptr, size_t *n, int delimiter, FILE *stream)

This function is like getline except that the character which tells it to stop reading is not necessarily newline. The argument delimeter specifies the delimeter character; getdelim keeps reading until it sees that character (or end of file).

The text is stored in lineptr, including the delimeter character and a terminating null. Like getline, getdelim makes lineptr bigger if it isn't big enough.

Function: char * fgets (char *s, int count, FILE *stream)

The fgets function reads characters from the stream stream up to and including a newline character and stores them in the string s, adding a null character to mark the end of the string. You must supply count characters worth of space in s, but the number of characters read is at most count - 1. The extra character space is used to hold the null character at the end of the string.

If the system is already at end of file when you call fgets, then the contents of the array s are unchanged and a null pointer is returned. A null pointer is also returned if a read error occurs. Otherwise, the return value is the pointer s.

Warning: If the input data has a null character, you can't tell. So don't use fgets unless you know the data cannot contain a null. Don't use it to read files edited by the user because, if the user inserts a null character, you should either handle it properly or print a clear error message. We recommend using getline instead of fgets.

Deprecated function: char * gets (char *s)

The function gets reads characters from the stream stdin up to the next newline character, and stores them in the string s. The newline character is discarded (note that this differs from the behavior of fgets, which copies the newline character into the string).

Warning: The gets function is very dangerous because it provides no protection against overflowing the string s. The GNU library includes it for compatibility only. You should always use fgets or getline instead.