There are four predefined streams. Don’t open or close them. Just use them.
cin
: standard input
cout
: standard output (for normal output)
cerr
: standard error (for error output)
clog
: standard error (for error output)
cerr
is unbuffered, clog
is buffered.
Use cerr
for error messages, clog
if you use standard error
for logging purposes.
The insertion operator, <<
, is used for output.
You may recognize it as the left shift operator. It’s that, too.
Isn’t operator overloading wonderful?
int i = 5<<4; double d = 4.5; char c = 'x'; const char *ccs = "My dog"; string s = " has fleas"; cout << i << ' ' << d << " " << c << "\n" << ccs << s << '\n';
80 4.5 x My dog has fleas
How can you tell if <<
means bit shift or insertion?
static int zero = 0; cout << "Alpha" << '\n' << 1/zero << '\n';
SIGFPE: Floating point exception
static int zero = 0; cout << "Beta" << '\n'; cout << 1/zero << '\n';
SIGFPE: Floating point exception
static int zero = 0; cout << "Gamma" << endl; cout << 1/zero << '\n';
Gamma SIGFPE: Floating point exception
static int zero = 0; cout << "Delta" << endl << 1/zero << '\n';
Delta SIGFPE: Floating point exception
cout << "alpha\n"; cout << "beta" << endl; cout << "gamma" << "\n"; cout << "delta" << '\n';
alpha beta gamma delta
endl
and \n
are synonymous.
They are not.
\n
means: Add a newline ('\n') to the output.
endl
means: Add a newline to the output,
and flush the output buffer.
endl
unless you really want to flush.
It’s not free, and it confuses those who know what it does.
The extraction operator, >>
, is used for input.
You may recognize it as the right shift operator. It’s that, too.
Isn’t operator overloading wonderful?
int i; cin >> i; // attempt to read an integer if (cin) // Is the stream in a happy state? cout << "Read i=" << i << '\n';
-or-
if (!(cin >> i)) // Could we read? cerr << "Input failed!\n";
Input may be chained, just like output:
int a, b, c; if ((cin>>a) && (cin>>b) && (cin>>c)) cout << "a=" << a << " b=" << b << " c=" << c << '\n';
-or-
int a, b, c; if (cin >> a >> b >> c) cout << "a=" << a << " b=" << b << " c=" << c << '\n';
The &&
forces left-to-right evaluation, so the numbers
are read in the proper order.
Consider this small file:
$ cat ~cs253/pub/ducks Huey (red) Dewey (blue) Louie (green)
To read an entire line, use getline()
:
ifstream in("/s/bach/a/class/cs253/pub/ducks"); string line; while (getline(in, line)) cout << line << '\n';
Huey (red) Dewey (blue) Louie (green)
Consider this small file:
$ cat ~cs253/pub/ducks Huey (red) Dewey (blue) Louie (green)
Extracting a string via >>
only reads a whitespace-delimited string.
ifstream in("/s/bach/a/class/cs253/pub/ducks"); string s; while (in >> s) cout << s << '\n';
Huey (red) Dewey (blue) Louie (green)
Consider this small file:
$ cat ~cs253/pub/ducks Huey (red) Dewey (blue) Louie (green)
To read a raw char
, without skipping whitespace, use get()
:
ifstream in("/s/bach/a/class/cs253/pub/ducks"); char c; while (in.get(c)) cout << c;
Huey (red) Dewey (blue) Louie (green)
Unlike getline
in the previous slide, get
is a method.
Consider this small file:
$ cat ~cs253/pub/ducks Huey (red) Dewey (blue) Louie (green)
Extracting a char
via >>
only reads a whitespace-delimited character,
which is rarely useful. That is, it skips whitespace.
ifstream in("/s/bach/a/class/cs253/pub/ducks"); char c; while (in >> c) cout << c;
Huey(red)Dewey(blue)Louie(green)
$ cat ~cs253/pub/ducks Huey (red) Dewey (blue) Louie (green)
To put a character back, use .unget()
:
ifstream in("/s/bach/a/class/cs253/pub/ducks"); char c; in >> c; cout << "First character: " << c << '\n'; in.unget(); // no argument string s; in >> s; cout << "First string: " << s << '\n';
First character: H First string: Huey
cin.eof()
This code is executed with no input,
yet it seems to read stuff.
while (!cin.eof()) { char c = 'X'; cin.get(c); cout << "Read '" << c << "'\n"; }
Read 'X'
while (!cin.eof()) { string line = "bogus"; getline(cin, line); cout << "Read '" << line << "'\n"; }
Read ''
while (!cin.eof()) { int n = 42; cin >> n; cout << "Read " << n << "\n"; }
Read 42
int n; while (!cin.eof()) { // BAD CODE! cin >> n; ... }
cin.eof()
does not mean “Will the next read hit end-of-file?”
cin.eof()
means “Did we already hit end-of-file?”
Here’s a better way to do it:
int n; while (cin >> n) { … }
int n; while (cin >> n) { … } if (!cin.eof()) cerr << "Read failed, but not at eof. Must be non-numeric data.\n";