The intent was to create architecture independent I/O by the standard of ANSI/ISO.
Most C++ I/O classes have names starting with basic_
. However, most of
them are typedefed into other names. I/O facilities were developed using
the template mechnaism alowing for easy conversions to character types
other than the traditional char
type.
Iostream objects cannot be declared using standard forward declarations,
instead, the <iosfwd>
header file should be included.
+----------+ | ios_base | +-----|----+ +--|--+ | ios +----> rdbuf() +------> streambuf* +----------|-----|----------+ | | +-----|-----+ +------|----+ | | streambuf* | | | istream <--+filebuf*+--> ostream +----------+ | | stringbuf* | | | +-----|--|--------++ +---|-------+ | | | | | | | | | | | | | +----|------+ | +-------|------+ +----|-----+ | +--------|--------+ | ifstream | | | istringstream| | ofstream | | | ostringstream | +-----------+ | +--------------+ +----------+ | +-----------------+ | +-------------+ | +----------+ iostream +----------+ +-------|-----+ +----|----+ | fstream | +---------+
class ios_base
defines the core of all I/O operations and offers facilities for inspecting the state of I/O streams and for output formatting.ios
implements the communication with a buffer used by streams, which is astreambuf
object, responsible for the actual I/O to/form the underlying device.iostream
objects do not perform I/O operations themselves but leave these the buffer with which they are associated.- It is possible read/write information into memory buffers instead of
files, for which the
istreamstream=/=ostringstream
is used. - Formating is to a great extent possible using the facilities defined
in the
ios
class, but also possbile to insert formatting commands directly into streams using manipulators. - Stream objects are the interface between the objects to be input or or
output and the
streambuf
which is responsible for the actual I/O to the device. This allows to construct a new kind ofstreambuf
for a new kind of device and use it in combination withistream
- andostream
-class facilities.iostream
objects perform formatting roles. Interfacing to new devices requires the construction of a new kind ofstreambuf
rather than a new kind of stream object. A wrapper class around stream classes eases the access to a special device, which is how thestringstream
classes were constructed.
The class std::ios_base
forms the foundation of all I/O operations,
and defines, among other things, facilities for inspecting the state of
I/O streams and most output formatting facilities.
The purpose of the class ios
is to provide the facilities of the class
basic_ios
, and to add several new facilites, all related to the
streambuf
object which is managed by objects of the class ios
.
std::sterambuf *ios::rdbuf()
: returnsiop a nter thestreambuf
object forming the interface between theios
object and the device with which theios
communicates.
Operations on streams may fail for various reasons. Whenever an operation fails, further operations on the stream are suspended. It is possible to inspect, set and possbily clear the condition state of streams, allowing a program to repair the problem rather than having to abort.
ios::badbit
: illegal reqeust at the level of thestreambuf
ios::eofbit
: end of fileios::failbit
: an operation by thestreambuf
object has failed, in which case, further such operations no longer work.ios::goodbit
: if none of the three above
streams may be be used in expressions expecting logical values, where
not fail()
is actually interpreted.
if (cin)
Formatting is controlled by flags, defined by the ios
class. These
flags may be manipulated in two ways: using specialized member functions
or using manipulators, which are directly inserted into or extracted
from streams. There is no special reason for using either method;
usually both methods are possible.
std::endl
should be avoided unless flushing the stream is explicitly
intended.
ostream
offers the basic output facilities; ofstream
allows to write
files; ostringstream
allows to write information to memory.
cout
, clog
, cerr
objects are all ostream objects. predefined with
predefined streambuf
objects. ostream
support both formatted and
binary output. <<
is formatted output.
.put(char c)
, .write(char const *buffer, int length)
may be used to
write binary files. The bytes written by write
are written to the
ostream
in an order depending on the endianness of t he underlying
hardware.
It is impossible to open an ofstream
using a file descriptor.
similar to output
Information written to one stream is actually written to another stream.
Redirection is commonly implemented ast the operating system level. An
implementation using streambuf
would be like
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char *argv[])
{
ofstream errlog;
streambuf *cerr_buffer = nullptr;
if (argc == 2) {
errlog.open(argv[1]);
cerr_buffer = cerr.rdbuf(errlog.rdbuf()); // it is important that the original buffer be saved
} else {
cerr << "Missing log names\n";
return 1;
}
cerr << "Several messages to stderr, msg 1\n";
cerr << "Several messages to stderr, msg 2\n";
cout << "Now inspect the contents of " <<
argv[1] << "... [Enter] ";
cin.get();
cerr << "Several messages to stderr, msg 3\n";
cerr.rdbuf(cerr_buffer);
cerr << "Done\n";
}
TODO