CS253: Software Development with C++

Spring 2021

Input/Output

Show Lecture.IO as a slide show.

CS253 I/O

I/O Class Hierarchy

				       ┌─────┐
				       │ ios │
				       └─────┘
					  △
					  │
			 ┌────────────────┴────────────────┐
			 │				   │
		    ┌────┴────┐			      ┌────┴────┐
		    │ istream │			      │ ostream │
		    └─────────┘			      └─────────┘
			 △				   △
			 │				   │
		  ┌──────┴───────┐		    ┌──────┴───────┐
		  │		 │		    │		   │
	    ┌─────┴────┐ ┌───────┴───────┐  ┌───────┴───────┐ ┌────┴─────┐
	    │ ifstream │ │ istringstream │  │ ostringstream │ │ ofstream │
	    └──────────┘ └───────────────┘  └───────────────┘ └──────────┘

The △ indicates inheritance.

More

			   ┌─────┐
			   │ ios │
			   └─────┘
			      △
			      │
	     ┌────────────────┴────────────────┐
	     │				       │
	┌────┴────┐			  ┌────┴────┐
	│ istream │			  │ ostream │
	└─────────┘			  └─────────┘
	     △				       △
	     │				       │
      ┌──────┴───────┐			┌──────┴───────┐
      │		     │			│	       │
┌─────┴────┐ ┌───────┴───────┐	┌───────┴───────┐ ┌────┴─────┐
│ ifstream │ │ istringstream │  │ ostringstream │ │ ofstream │
└──────────┘ └───────────────┘  └───────────────┘ └──────────┘

Methods & Operator Overloading

			   ┌─────┐
			   │ ios │
			   └─────┘
			      △
			      │
	     ┌────────────────┴────────────────┐
	     │				       │
	┌────┴────┐			  ┌────┴────┐
	│ istream │			  │ ostream │
	└─────────┘			  └─────────┘
	     △				       △
	     │				       │
      ┌──────┴───────┐			┌──────┴───────┐
      │		     │			│	       │
┌─────┴────┐ ┌───────┴───────┐  ┌───────┴───────┐ ┌────┴─────┐
│ ifstream │ │ istringstream │  │ ostringstream │ │ ofstream │
└──────────┘ └───────────────┘  └───────────────┘ └──────────┘

What Header Files Define What

<sstream> <fstream> <iostream> <iomanip>
objects manipulators

istringstream ostringstream stringstream

ifstream ofstream fstream

cin cout cerr clog

These don’t take an argument:

boolalpha noboolalpha showbase noshowbase showpoint noshowpoint showpos noshowpos skipws noskipws uppercase nouppercase left right internal dec hex oct fixed scientific

These do take an argument

resetiosflags setiosflags setbase setfill setprecision setw (non-sticky)

strange type?

Consider the error message from this bad code:

cout.zork();
c.cc:1: error: 'std::ostream' {aka 'class std::basic_ostream<char>'} has no 
   member named 'zork'

basic_ostream

Why!?

w-streams

wchar_t

char c = 'X';
wchar_t wc = L'⻥';
cout << sizeof(c) << '\n'
     << sizeof(wc) << '\n';
1
4

basic_whatever<type>

Unformatted output

We’re familiar with formatted I/O using << or >>:

cout << "π ≈ " << 355/113.0 << endl;
π ≈ 3.14159

There’s also unformatted output:

cout.put('h');
cout.put('i');
char data[] = " there\nextra";
cout.write(data, 7);
hi there

Unformatted input

Similarly, there is unformatted input:

ifstream in("/etc/resolv.conf");
string s;
getline(in, s);
cout << "First: " << s << '\n';
char c;
while (in.get(c)) {
    if (c == '.') c = '*';
    cout << c;
}
First: search cs.colostate edu colostate.edu
nameserver 129*82*45*181
nameserver 129*82*103*78
nameserver 129*82*103*79

seek/tell


Diogenes

seek/tell methods


Misuse of .open()

ifstream and ofstream both inherited fstream::open():

ifstream in;
const string home = getpwnam("cs253")->pw_dir;
in.open(home+"/pub/ducks");
char c;
while (in.get(c))
    cout << c;
Huey (red)
Dewey (blue)
Louie (green)

Why have that extra step? Just associate the filename at object construction:

const string home = getpwnam("cs253")->pw_dir;
ifstream in(home+"/pub/ducks");
char c;
while (in.get(c))
    cout << c;
Huey (red)
Dewey (blue)
Louie (green)

Misuse of .eof()

ifstream in("/etc/resolv.conf");
string line;

while (!in.eof()) {
    getline(in, line);
    cout << line << '\n';
}
search cs.colostate edu colostate.edu
nameserver 129.82.45.181
nameserver 129.82.103.78
nameserver 129.82.103.79

Where did that extra line come from?

The right way to detect end-of-file

Don’t inquire in advance—just go ahead and read. It will succeed or fail:

ifstream in("/etc/resolv.conf");
string line;
while (getline(in, line))
    cout << line << '\n';
search cs.colostate edu colostate.edu
nameserver 129.82.45.181
nameserver 129.82.103.78
nameserver 129.82.103.79

Or, with fewer source lines and a reduced scope for line:

ifstream in("/etc/resolv.conf");
for (string line; getline(in, line); )
    cout << line << '\n';
search cs.colostate edu colostate.edu
nameserver 129.82.45.181
nameserver 129.82.103.78
nameserver 129.82.103.79