iostreams


The iostreams classes introduce the notion of a stream, a mechanism for sending (or getting) C++ variables to (or from) files. The iostream classes also support string I/O, and enable developers to easily add support for user-defined data types, as well as user-defined streams. Given the following data:

int i = 17;
float f = 3.14159;
char buf[100];
strcpy( buf, "This is a C string" );
The following code performs stream outputs:

cout << "i = " << i;
cout << "f = " << f;
cout << "buf = " << buf;
and the following code performs input:

cin >> i >> f >> buf;
Note that this mechanism does not require programmers to supply data type information in the I/O statements, and the syntax for all data types is consistent. Compare the preceding statement to their C equivalents:

printf( "i = %d", i );             /* output */
printf( "f = %f", f );
printf( "p = %s", p );

scanf( "%d, %f, %s", &i, &f, p );  /* input */
The printf and scanf data-type specifiers (%d, %f, %s) must match the parameters (i, f, p) both by order and by type (%d for int, %f for float, etc.). Also, in these C I/O statements, programmers must treat pointer and non-pointer variables differently, at least in the scanf (and other input) statements. The C program must pass the address of non-pointer variables (as in &i or &f) to scanf, but it must pass a variable like p directly by name, since it is already an address. This inconsistency leads to various sorts of problems. For example, when a type or positional mismatch exists between type specifiers and data values, the programmers can spend time looking for an error that doesn't even exist!

The (possibly) mysterious variables cout and cin in the preceding C++ example are C++ pre-defined variables corresponding to the pre-opened C files stdout and stdin. Both the C++ variables and their corresponding C streams refer to the redirectable I/O streams provided by DOS, UNIX, etc. The C printf and scanf functions are convenient equivalents for:

fprintf( stdout, ...
and

fscanf( stdin, ...
The iostreams classes also support I/O to explicitly named files, as in:

fstream of( "file.dat", ios::in );

of << "i, f, p = " << i << f << p;
as well as string I/O corresponding to sprintf and scanf:

char buf[200];
ostrstream os( buf, sizeof( buf ) );

os << "i, f, p = "<< i << f << p;
I/O manipulators, another important aspect of streams, allow programs to control streams in specialized ways, such as:

cout << "this is 75 in hex: " << hex << 75 << endl;
Using I/O manipulators, programmers can specify type-specific attributes, such as hex notation for a following value, or insert control characters like endl (for end of line) in a portable and mnemonic way.