no copyright!iostream-objects.3

IOStream Objects

Synopsis

#include <iostream>

std::istream std::cin
std::ostream std::cout
std::ostream std::cerr
std::ostream std::clog

std::wistream std::wcin
std::wostream std::wcout
std::wostream std::wcerr
std::wostream std::wclog
    

Description

There is a set of stream objects predefined in the C++ standard library for access to standard input and output streams. These objects are declared in the header <iostream> and have a close relationship to the predefined streams defined by the C standard library. Each of the predefined C++ streams relates to a specific C stream:

Purpose Narrow Wide C stream
Standard Input std::cin std::wcin stdin
Standard Output std::cout std::wcout stdout
Standard Error std::cerr std::wcerr stderr
Standard Logging std::clog std::wclog stderr

Mixing C and C++ I/O Operations

The operations on corresponding C and C++ streams is synchronized by default. This basically means that the streams behave as if they are unbuffered: The input streams extract only those characters immediately consumed but do not buffer any characters from the standard input except potentially in a buffer shared by the C and the C++ operations. Thus, if C and C++ standard streams are synchronized (see sync_with_stdio()) it is save to read characters from the standard input alternatingly using C or C++ functions. Correspondingly, it is save to write character to one of the standard output streams alternatingly using C or C++ functions if the C and C++ standard streams are synchronized (see sync_with_stdio() below).

Mixing Wide and Narrow Operations

There is no synchronization between the narrow and wide character equivalents: After the first narrow or wide character operation is performed on one of the standard streams, it is not legal to use the other character type for the corresponding stream. Thus, for each of the three groups of streams (standard input, standard output, and standard error) you can only use narrow or wide character operations but you cannot mix them in the same run of a program.

Construction and Destruction Times

One peculiarity of the standard IOStream objects are their construction and destruction times: In general, the order of construction of global objects defined in different translation units is undefined. This is not true for the standard IOStream objects: It is guaranteed that the standard stream objects are constructed prior or during the first time an object of type ios_base::Init is constructed. Thus, to make sure that the standard stream objects are indeed constructed when a certain global object (more precisely, an object with static linkage) is constructed, you can just define a static object of type ios_base::Init prior to the definition of your object:
	namespace { std::ios_base::Init dummy; }
        // your object definition goes here
      
Actually, corresponding objects should be defined by the implementation of the C++ standard library if they are indeed necessary but this is not explicitly required. One reason for not requiring construction of such objects in the C++ standard library implementation is to avoid paging in all object files resulting from translation units which include the header <iostream>. For this particular implementation, the standard stream objects are guaranteed to be constructed prior to the first time they are used, even without construction of the Init objects. Although this is what was intended by the standard, it is not really guaranteed. On the other hand, it is guaranteed that the standard stream objects are never destructed. This is two major effects:
  1. It is save to use the standard streams during destruction of global objects (that is, objects with static linkage).
  2. You have to make sure that output written to the standard streams during destruction of global objects is not just buffered but is really written. This is easily accomplished by terminating the lines writing the output either with writing the manipulator std::endl or with writing the manipulator std::flush.

Details on the Standard Streams

std::cin

std::cin

The stream std::cin is associated with the C stream stdin and thus used for the standard input stream. There is no definition what the standard input stream really is but is reasonable to assume that this stream is connected to the keyboard. However, even if this is sometime true, it is often possible to redirect this stream to read from some other source, e.g. from a file or from the output of some other process. Initially, std::cin is "tied" (see the definition of basic_ios::tie()) to the stream std::cout. Other than this, the stream parameters are initialized according to the defaults defined by basic_ios::init(). std::cout

std::cout

The stream std::cout is associated with the C stream stdout and thus used for the standard output stream. Again, there is no definition where this stream really writes to. It is reasonable to assume that the standard output stream writes to a console but it is also possible that this stream is redirected to a file or to the standard input stream of another process. The stream parameter are initialized according to the defaults defined in basic_ios::init(). std::cerr

std::cerr

The stream std::cerr is associated with the C stream stderr and thus used for the standard error stream. Again, there is no definition where this stream really writes to. It is reasonable to assume that the standard output stream writes to a console but it is also possible that this stream is redirected to a file or to the standard input stream of another process. Normally, standard output and standard error are redirected separately such that error messages may still be displayed even if the standard output stream is redirected to a file or a process. The formatting flag ios_base::unitbuf is set for this stream basically resulting in unbuffered operation. Other than this the stream parameter are initialized according to the defaults defined in basic_ios::init(). std::clog

std::clog

The stream std::clog is also associated with the C stream stderr and thus also writes to the standard error stream. The difference to std::cerr is, that the formatting flag ios_base::unitbuf is not set for this stream: The stream parameter are initialized according to the defaults defined in basic_ios::init(). std::wcin std::wcout std::wcerr std::wclog

std::wcin, std::wcout, std::wcerr, and std::wclog

The streams std::wcin, std::wcout, std::wcerr, and std::wclog are setup corresponding to their narrow counterparts. The only difference is that these streams are used to write wide characters to the standard streams.

See Also

basic_ios(3), basic_istream(3), basic_ostream(3), ios_base(3)
Copyright © 1999 Dietmar Kühl, Claas Solutions (dietmar.kuehl@claas-solutions.de)