Chapter 8. The IO Library

8.1 The IO classes

iostream defines the basic types used to read from and write to a stream, fstream defines the types used to read and write named files, and sstream defines the types used to read and write in-memory strings.

8.1.1 No Copy or Assign for IO Objects

The IO objects cannot be copied and assigned. Since we can't copy the IO types, we cannot have a parameter or return type this is one of the stream types. Functions that do IO typically pass and return the stream through references.

8.1.2 Condition State

The IO classes define functions and flags, that let us access and manipulate the condition state of a stream.

The badbit indicates a system-level failure, such as an unrecoverable read or write error. The failbit is set after a recoverable error, such as reading a character when numeric data was expected. Reaching end-of-file sets both eofbit and failbit. The goodbit, which is guaranteed to have the value 0, indicates no failures on the stream. If any of badbit, failbit, or eofbit are set, then a condition that evaluates that stream will fail.

IO Library Condition State

Description

strm::iostate

a machine-dependent integral type that represents the condition state of a stream.

strm::badbit

indicate that a stream is corrupted.

strm::failbit

indicate that an IO operation failed.

strm::eofbit

indicate that a stream hit end-of-file.

strm::goodbit

indicate that a stream is not in an error state.

s.eof()

true if eofbit in the stream is set.

s.fail()

true if failbit or badbit in the stream is set.

s.bad()

true if badbit in the stream is set.

s.good()

true if the stream is in valid state.

s.clear()

reset all condition values in the stream to valid state.

s.clear(flag)

reset the condition of the stream to flags. Type of flags is strm::iostate.

s.setstate()

adds specified condition to the stream.

s.rdstate()

return current condition state.

8.1.3 Managing the Output Buffer

Each output stream manages a buffer, which it uses to hold the data that the program reads and writes.

Using a buffer allows the operating system to combine several output operations from our program into a single system-level write. Because writing to a device can by time-consuming, letting the operating system combine several output operations into a single write can provide an important performance boost.

There are several conditions that cause the buffer to be flushed:

  • The program completes normally.

  • At some indeterminate time, the buffer can become full, in which case it will be flushed before writing the next value.

  • We can flush the buffer explicitly using a manipulator such as endl.

  • We can use the unitbuf manipulator to set the stream's internal state to empty the buffer after each output operation. By default, unitbuf is set for cerr, so that writes to cerr, are flushed immediate.

  • An output stream might be tied to another stream. By default, cin and cerr are both tied to cout. Hence, reading cin or writing to cerr flushes the buffer in cout.

Flushing the Output Buffer

cout << "hi" << endl;
cout << "hi" << flush;
cout << "hi" << ends;

cout << unitbuf;
cout << "hi";
cout << nounitbuf;

Tying Input and Output Streams Together

Wen an input stream is tied to an output stream, any attempt to read the input stream will first flush the buffer associated with the output stream.

Interactive systems usually should tie their input stream to their output stream.

There are two overloaded version of tie: One version takes no argument and returns a pointer to the output stream, if any, to which this object is currently tied. The function returns the null pointer if the stream is not tied.

The second version of tie takes a pointer to an ostream and ties itself to that ostream.

cin.tie(&cout);

8.2 File Input and Output

The fstream header defines three types to support file IO: ifstream to read from a given file, ofstream to write to a given file, and fstream, which reads and writes a given file.

fstream Specific Operation

Description

fstream fstrm;

creates an unbound file stream.

fstream fstrm(s);

creates a file stream and opens the file named s.

fstream fstrm(s, mode);

open the file s in the given mode.

fstrm.open(s)

opens the file named by the s and binds that file to the file stream.

fstrm.close()

closes the file stream.

fstrm.is_open()

indicating whether the file associated with file stream was successfully opened and has not been closed.

8.2.1 Using File Stream Objects

When we create a file stream, we can provide a file name. When we supply a file name, open is called automatically.

ifstream in(ifile);
ofstream out;
out.open(ifile + ".copy");
in.close();

When an fstream object is destroyed, close is called automatically.

8.2.2 File Modes

File Mode

Description

in

open for input.

out

open for output.

app

seek to the end before every write.

ate

seek to the end immediately after the open.

trunc

truncate the file.

binary

do IO operators in binary mode.

  • out may be set only for an ofstream or fstream object.

  • in may be set only for an ifstream or fstream object.

  • trunc may be set only when out is also specified.

  • app mode may be specified so long as trunc is not. If app is specified, the file is always opened in output mode, even if out was not explicitly specified.

  • By default, a file opened in out mode is truncated even if we do not specify trunc.

  • The ate and binary modes may be specified on any file stream object type and in combination with any other file modes.

ofstream out("file1");
ofstream out1("file1", ofstream::out);
ofstream out2("file1", ofstream::out | ofstream::trunc);

8.3 string Streams

The istringstream type reads a string, ostringstream writes a string, and stringstream reads and writes the string.

stringstream Specific Operations

Description

sstream strm;

strm is an unbound stringstream.

sstream strm(s);

strm is an sstream that holds a copy of the string s.

strm.str();

return a copy of the string that strm holds

strm.str(s);

copies the string s into strm.

8.3.1 Using an istringstream

An istringstream is often used when we have some work to do on an entire line, and other work to do with individual words within a line.

string line;
istringstream record(line):

8.3.2 Using ostringstream

An ostringstream is useful when we need to build up our output a little at a time but do not want to print the output until later.

Last updated

Was this helpful?