In data input/output, it would lead to poor efficiency if each call of an input/output function, which handles a single character, drove the input/output device and the OS functions. To solve this problem, a storage area called a buffer is normally provided, and the data in the buffer is input or output at one time.
From the viewpoint of the program, on the other hand, it is more convenient to call input/output functions for each character.
Using the library functions, character-by-character input/output can be performed efficiently without awareness of the buffer status within the program by automatically performing buffer management.
Those library functions enable a programmer to write a program considering the input/output as a single data stream, making the programmer be able to implement data input/output efficiently without being aware of the detailed procedure. Such capability is called stream input/output.
The buffer and other information required for the stream input/output described above are stored in a single structure, defined by the name FILE in the <stdio.h> standard include file.
In stream input/output, all files are handled as having a FILE structure data structure. Files of this kind are called stream files. A pointer to this FILE structure is called a file pointer, and is used to specify an input/output file.
The file pointer is defined as
When a file is opened by the fopen function, etc., the file pointer is returned. If the open processing fails, NULL is returned. Note that if a NULL pointer is specified in another stream input/output function, that function will end abnormally. After opening a file, be sure to check the file pointer value to see whether the open processing has been successful.
There are two library function implementation methods: functions and macros.
A function has the same interface as an ordinary user-written function, and is incorporated during linkage. A macro is defined using a #define statement in the standard include file relating to the function.
The following points must be noted concerning macros:
Macros are expanded automatically by the preprocessor, and therefore a macro expansion cannot be invalidated even if the user declares a function with the same name. |
If an expression with a side effect (assignment expression, increment, decrement) is specified as a macro parameter, its result is not guaranteed. |
If the following definition is made:
#define MACRO(a) ((a) >= 0 ? (a) : -(a))
is in the program, the macro will be expanded as follows:
X = ((a++) >= 0 ? (a++) : -(a++))
a will be incremented twice, and the resultant value will be different from the absolute value of the initial value of a.
In functions such as getc, getchar, and fgetc, which input data from a file, EOF is the value returned at end-of-file. The name EOF is defined in the <stdio.h> standard include file.
This is the value indicating that a pointer is not pointing at anything. The name NULL is defined in the <stddef.h> standard include file.
The end of a string in C/C++ is indicated by the characters \0. String parameters in library functions must also conform to this convention. The characters \0 indicating the end of a string are called null characters.
With some library functions, a return value is used to determine the result (such as whether the specified processing succeeded or failed). In this case, the return value is called the return code.
Many systems have special file formats to store data. To support this facility, library functions have two file formats: text files and binary files.
A text file is used to store ordinary text, and consists of a collection of lines. In text file input, the new-line character (\n) is input as a line separator. In output, output of the current line is terminated by outputting the new-line character (\n). Text files are used to input/output files that store standard text for each system. With text files, characters input or output by a library function do not necessarily correspond to a physical stream of data in the file.
A binary file is configured as a row of byte data. Data input or output by a library function corresponds to a physical list of data in the file.
Files that can be used as standard by input/output library functions by default without preparations such as opening file are called standard input/output files. Standard input/output files comprise the standard input file (stdin), standard output file (stdout), and standard error output file (stderr).
Standard file to be input to a program.
Standard file to be output from a program.
Standard file for storing output of error messages, etc., from a program.
Floating-point numbers are numbers represented by approximation of real numbers. In a C source program, floating-point numbers are represented by decimal numbers, but inside the computer they are normally represented by binary numbers.
In the case of binary numbers, the floating-point representation is as follows:
2n × m (n: integer, m: binary fraction)
Here, n is called the exponent of the floating-point number, and m is called the mantissa. The numbers of bits to represent n and m are normally fixed so that a floating-point number can be represented using a specific data size.
Some terms relating to floating-point numbers are explained below.
An integer value indicating the number of distinct digits in the number system used by a floating-point number (10 for decimal, 2 for binary, etc.). The radix is normally 2.
Rounding is performed when an intermediate result of an operation of higher precision than a floating-point type is stored as that floating-point type. There is rounding up, rounding down, and half-adjust rounding (i.e., in binary representation, rounding down 0 and rounding up 1).
When a floating-point number is represented in the form 2n × m, the same number can be represented in different ways.
[Format] The following two expressions represent the same value.
25 × 1.0 (2) ((2) indicates a binary number)
Usually, a representation in which the leading digit is not 0 is used, in order to secure the number of valid digits. This is called a normalized floating-point number, and the operation that converts a floating-point number to this kind of representation is called normalization.
When saving an intermediate result of a floating-point operation, data one bit longer than the actual floating-point number is normally provided in order for rounding to be carried out. However, this alone does not permit an accurate result to be achieved in the event of digit dropping, etc. For this reason, the intermediate result is saved with an extra bit, called a guard bit.
This is a string that indicates the kind of processing to be carried out on a file when it is opened. There are 12 different modes, as shown in Table 7.1.
Definitions differ for each compiler.
The following two data items are held for each stream file: (1) an error indicator that indicates whether or not an error has occurred during file input/output, and (2) an end-of-file indicator that indicates whether or not the input file has ended.
These data items can be referenced by the ferror function and the feof function, respectively.
With some functions that handle stream files, error occurrence and end-of-file information cannot be obtained from the return value alone. The error indicator and end-of-file indicator are useful for checking the file status after execution of such functions.
Stream files that can be read or written at any position within the file, such as disk files, have an associated data item called a file position indicator that indicates the current read/write position within the file.
File position indicators are not used with stream files that do not permit the read/write position within the file to be changed, such as terminals.