Skip to content

Latest commit

 

History

History
203 lines (162 loc) · 6.94 KB

io_stream_library.org

File metadata and controls

203 lines (162 loc) · 6.94 KB

Overview

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.

Architecture

                         +----------+
                         | 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 a streambuf 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 of streambuf for a new kind of device and use it in combination with istream- and ostream-class facilities. iostream objects perform formatting roles. Interfacing to new devices requires the construction of a new kind of streambuf rather than a new kind of stream object. A wrapper class around stream classes eases the access to a special device, which is how the stringstream classes were constructed.

Class ios_base

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.

class ios

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 the streambuf object forming the interface between the ios object and the device with which the ios 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 the streambuf
  • ios::eofbit: end of file
  • ios::failbit: an operation by the streambuf 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.

Output

ostream offers the basic output facilities; ofstream allows to write files; ostringstream allows to write information to memory.

ostream

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.

Input

similar to output

Redirecting streams

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";
}

Reading and Writing

TODO