Input/output via <iostream>
and <cstdio>
Why should I use <iostream>
instead of the traditional <cstdio>
?
Increase type safety, reduce errors, allow extensibility, and provide inheritability.
printf()
is arguably not broken, and scanf()
is perhaps livable despite being error prone, however both are limited
with respect to what C艹 I/O can do. C艹 I/O (using <<
and >>
) is, relative to C (using printf()
and
scanf()
):
- More type-safe: With
<iostream>
, the type of object being I/O’d is known statically by the compiler. In contrast,<cstdio>
uses"%"
fields to figure out the types dynamically. - Less error prone: With
<iostream>
, there are no redundant"%"
tokens that have to be consistent with the actual objects being I/O’d. Removing redundancy removes a class of errors. - Extensible: The C艹
<iostream>
mechanism allows new user-defined types to be I/O’d without breaking existing code. Imagine the chaos if everyone was simultaneously adding new incompatible"%"
fields toprintf()
andscanf()
?! - Inheritable: The C艹
<iostream>
mechanism is built from real classes such asstd::ostream
andstd::istream
. Unlike<cstdio>
’sFILE*
, these are real classes and hence inheritable. This means you can have other user-defined things that look and act like streams, yet that do whatever strange and wonderful things you want. You automatically get to use the zillions of lines of I/O code written by users you don’t even know, and they don’t need to know about your “extended stream” class.
Why does my program go into an infinite loop when someone enters an invalid input character?
For example, suppose you have the following code that reads integers from std::cin
:
#include <iostream>
int main()
{
std::cout << "Enter numbers separated by whitespace (use -1 to quit): ";
int i = 0;
while (i != -1) {
std::cin >> i; // BAD FORM — See comments below
std::cout << "You entered " << i << '\n';
}
// ...
}
The problem with this code is that it lacks any checking to see if someone entered an invalid input character. In
particular, if someone enters something that doesn’t look like an integer (such as an ‘x’), the stream std::cin
goes
into a “failed state,” and all subsequent input attempts return immediately without doing anything. In other words, the
program enters an infinite loop; if 42
was the last number that was successfully read, the program will print the
message You entered 42
over and over.
An easy way to check for invalid input is to move the input request from the body of the while
loop into the
control-expression of the while
loop. E.g.,
#include <iostream>
int main()
{
std::cout << "Enter a number, or -1 to quit: ";
int i = 0;
while (std::cin >> i) { // GOOD FORM
if (i == -1) break;
std::cout << "You entered " << i << '\n';
}
// ...
}
This will cause the while loop to exit either when you hit end-of-file, or when you enter a bad integer, or when you
enter -1
.
(Naturally you can eliminate the break
by changing the while
loop expression from while (std::cin >> i)
to
while ((std::cin >> i) && (i != -1))
, but that’s not really the point of this FAQ since this FAQ has to do with
iostreams rather than generic structured programming guidelines.)
How can I get std::cin
to skip invalid input characters?
Use std::cin.clear()
and std::cin.ignore()
.
#include <iostream>
#include <limits>
int main()
{
int age = 0;
while ((std::cout << "How old are you? ")
&& !(std::cin >> age)) {
std::cout << "That's not a number; ";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
std::cout << "You are " << age << " years old\n";
// ...
}
Of course you can also print the error message when the input is out of range. For example, if you wanted the age
to
be between 1 and 200, you could change the while
loop to:
// ...
while ((std::cout << "How old are you? ")
&& (!(std::cin >> age) || age < 1 || age > 200)) {
std::cout << "That's not a number between 1 and 200; ";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
// ...
Here’s a sample run:
How old are you? foo
That's not a number between 1 and 200; How old are you? bar
That's not a number between 1 and 200; How old are you? -3
That's not a number between 1 and 200; How old are you? 0
That's not a number between 1 and 200; How old are you? 201
That's not a number between 1 and 200; How old are you? 2
You are 2 years old
How does that funky while (std::cin >> foo)
syntax work?
See the previous FAQ for an example of the “funky while (std::cin >> foo)
syntax.”
The expression (std::cin >> foo)
calls the appropriate operator>>
(for example, it calls the operator>>
that takes
an std::istream
on the left and, if foo
is of type int
, an int&
on the right). The std::istream
operator>>
functions return their left argument by convention, which in this case means it will return std::cin
. Next the
compiler notices that the returned std::istream
is in a boolean context, so it converts that std::istream
into a
boolean.
To convert an std::istream
into a boolean, the compiler calls a member function called
std::istream::operator void*()
. This returns a void*
pointer, which is in turn converted to a boolean (NULL
becomes false
, any other pointer becomes true
). So in this case the compiler generates a call to
std::cin.operator void*()
, just as if you had casted it explicitly such as (void*) std::cin
.
The operator void*()
cast operator returns some non-NULL
pointer if the stream is in a good state, or NULL
if
it’s in a failed state. For example, if you read one too many times (e.g., if you’re already at end-of-file), or if
the actual info on the input stream isn’t valid for the type of foo
(e.g., if foo
is an int
and the data is an ‘x’
character), the stream will go into a failed state and the cast operator will return NULL
.
The reason operator>>
doesn’t simply return a bool
(or void*
) indicating whether it succeeded or failed is to
support the “cascading” syntax:
std::cin >> foo >> bar;
The operator>>
is left-associative, which means the above is parsed as:
(std::cin >> foo) >> bar;
In other words, if we replace operator>>
with a normal function name such as readFrom()
, this becomes the
expression:
readFrom( readFrom(std::cin, foo), bar);
As always, we begin evaluating at the innermost expression. Because of the left-associativity of operator>>
, this
happens to be the left-most expression, std::cin >> foo
. This expression returns std::cin
(more precisely, it
returns a reference to its left-hand argument) to the next expression. The next expression also returns (a reference
to) std::cin
, but this second reference is ignored since it’s the outermost expression in this “expression statement.”
Why does my input seem to process past the end of file?
Because the eof state may not get set until after a read is attempted past the end of file. That is, reading the last byte from a file might not set the eof state. E.g., suppose the input stream is mapped to a keyboard — in that case it’s not even theoretically possible for the C艹 library to predict whether or not the character that the user just typed will be the last character.
For example, the following code might have an off-by-one error with the count i
:
int i = 0;
while (! std::cin.eof()) { // WRONG! (not reliable)
std::cin >> x;
++i;
// Work with x ...
}
What you really need is:
int i = 0;
while (std::cin >> x) { // RIGHT! (reliable)
++i;
// Work with x ...
}
Why is my program ignoring my input request after the first iteration?
Because the numerical extractor leaves non-digits behind in the input buffer.
If your code looks like this:
char name[1000];
int age;
for (;;) {
std::cout << "Name: ";
std::cin >> name;
std::cout << "Age: ";
std::cin >> age;
}
What you really want is:
for (;;) {
std::cout << "Name: ";
std::cin >> name;
std::cout << "Age: ";
std::cin >> age;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Of course you might want to change the for (;;)
statement to while (std::cin)
, but don’t confuse that with skipping
the non-numeric characters at the end of the loop via the line: std::cin.ignore(...);
.
Should I end my output lines with std::endl
or '\n'
?
Using std::endl
flushes the output buffer after sending a '\n'
, which means std::endl
is more expensive in
performance. Obviously if you need to flush the buffer after sending a '\n'
, then use std::endl
; but if you don’t
need to flush the buffer, the code will run faster if you use '\n'
.
This code simply outputs a '\n'
:
void f()
{
std::cout << /*...stuff...*/ << '\n';
}
This code outputs a '\n'
, then flushes the output buffer:
void g()
{
std::cout << /*...stuff...*/ << std::endl;
}
This code simply flushes the output buffer:
void h()
{
std::cout << /*...stuff...*/ << std::flush;
}
Note: all three of the above examples require #include <iostream>
How can I provide printing for my class
Fred
?
Use operator
overloading to provide a friend
left-shift operator, operator<<
.
#include <iostream>
class Fred {
public:
friend std::ostream& operator<< (std::ostream& o, const Fred& fred);
// ...
private:
int i_; // Just for illustration
};
std::ostream& operator<< (std::ostream& o, const Fred& fred)
{
return o << fred.i_;
}
int main()
{
Fred f;
std::cout << "My Fred object: " << f << "\n";
// ...
}
We use a non-member function (a friend
in this case) since the Fred
object is the right-hand operand of
the <<
operator. If the Fred
object was supposed to be on the left hand side of the <<
(that is,
myFred << std::cout
rather than std::cout << myFred
), we could have used a member function named operator<<
.
Note that operator<<
returns the stream. This is so the output operations can be cascaded.
But shouldn’t I always use a printOn()
method rather than a friend
function?
No.
The usual reason people want to always use a printOn()
method rather than a friend
function is because they
wrongly believe that friends violate encapsulation and/or that friends are evil. These beliefs are naive and wrong:
when used properly, friends can actually enhance encapsulation.
This is not to say that the printOn()
method approach is never useful. For example, it is useful when providing
printing for an entire hierarchy of classes. But if you use a printOn()
method, it should
normally be protected
, not public
.
For completeness, here is “the printOn()
method approach.” The idea is to have a member function, often called
printOn()
, that does the actual printing, then have operator<<
call that printOn()
method. When it is done
wrongly, the printOn()
method is public
so operator<<
doesn’t have to be a friend
— it can be a simple
top-level function that is neither a friend
nor a member of the class. Here’s some sample code:
#include <iostream>
class Fred {
public:
void printOn(std::ostream& o) const;
// ...
};
// operator<< can be declared as a non-friend [NOT recommended!]
std::ostream& operator<< (std::ostream& o, const Fred& fred);
// The actual printing is done inside the printOn() method [NOT recommended!]
void Fred::printOn(std::ostream& o) const
{
// ...
}
// operator<< calls printOn() [NOT recommended!]
std::ostream& operator<< (std::ostream& o, const Fred& fred)
{
fred.printOn(o);
return o;
}
People wrongly assume that this reduces maintenance cost “since it avoids having a friend function.” This is a wrong assumption because:
- The member-called-by-top-level-function approach has zero benefit in terms of maintenance cost. Let’s say
it takes N lines of code to do the actual printing. In the case of a
friend
function, those N lines of code will have direct access to the class’sprivate
/protected
parts, which means whenever someone changes the class’sprivate
/protected
parts, those N lines of code will need to be scanned and possibly modified, which increases the maintenance cost. However using theprintOn()
method doesn’t change this at all: we still have N lines of code that have direct access to the class’sprivate
/protected
parts. Thus moving the code from afriend
function into a member function does not reduce the maintenance cost at all. Zero reduction. No benefit in maintenance cost. (If anything it’s a bit worse with theprintOn()
method since you now have more lines of code to maintain since you have an extra function that you didn’t have before.) - The member-called-by-top-level-function approach makes the class harder to use, particularly by programmers
who are not also class designers. The approach exposes a
public
method that programmers are not supposed to call. When a programmer reads thepublic
methods of the class, they’ll see two ways to do the same thing. The documentation would need to say something like, “This does exactly the same as that, but don’t use this; instead use that.” And the average programmer will say, “Huh? Why make the methodpublic
if I’m not supposed to use it?” In reality the only reason theprintOn()
method ispublic
is to avoid granting friendship status tooperator<<
, and that is a notion that is somewhere between subtle and incomprehensible to a programmer who simply wants to use the class.
Net: the member-called-by-top-level-function approach has a cost but no benefit. Therefore it is, in general, a bad idea.
Note: if the printOn()
method is protected
or private
, the second objection doesn’t apply. There are cases when
that approach is reasonable, such as when providing printing for an entire hierarchy of classes.
Note also that when the printOn()
method is non-public
, operator<<
needs to be a friend
.
How can I provide input for my class
Fred
?
Use operator
overloading to provide a friend
right-shift operator, operator>>
.
This is similar to the output operator, except the parameter doesn’t have a
const
: “Fred&
” rather than “const Fred&
”.
#include <iostream>
class Fred {
public:
friend std::istream& operator>> (std::istream& i, Fred& fred);
// ...
private:
int i_; // Just for illustration
};
std::istream& operator>> (std::istream& i, Fred& fred)
{
return i >> fred.i_;
}
int main()
{
Fred f;
std::cout << "Enter a Fred object: ";
std::cin >> f;
// ...
}
Note that operator>>
returns the stream. This is so the input operations can be cascaded and/or used in a while
loop or if
statement.
How can I provide printing for an entire hierarchy of classes?
Provide a friend
operator<<
that calls a protected
virtual
function:
class Base {
public:
friend std::ostream& operator<< (std::ostream& o, const Base& b);
// ...
protected:
virtual void printOn(std::ostream& o) const = 0; // Or plain virtual; see below
};
inline std::ostream& operator<< (std::ostream& o, const Base& b)
{
b.printOn(o);
return o;
}
class Derived : public Base {
public:
// ...
protected:
virtual void printOn(std::ostream& o) const;
};
void Derived::printOn(std::ostream& o) const
{
// ...
}
The end result is that operator<<
acts as if it were dynamically bound, even though it’s a friend
function. This is called the Virtual Friend Function Idiom.
Note that derived classes override printOn(std::ostream&)
const
. In particular, they do not provide their own
operator<<
.
As to whether Base::printOn()
is plain virtual or pure virtual, consider making it a plain virtual
(without the “= 0
”) if you can implement that function with code that would otherwise be repeated in two or more
derived classes. However if Base
is a ABC with little or no member data, you might not be able to provide
a meaningful definition for Base::printOn()
and you should make it pure virtual. If you’re not sure, make it pure
virtual, at least until you get a better handle on the derived classes.
How can I open a stream in binary mode?
Use std::ios::binary
.
Some operating systems differentiate between text and binary modes. In text mode, end-of-line sequences and
possibly other things are translated; in binary mode, they are not. For example, in text mode under Windows, "\r\n"
is
translated into "\n"
on input, and the reverse on output.
To read a file in binary mode, use something like this:
#include <string>
#include <iostream>
#include <fstream>
void readBinaryFile(const std::string& filename)
{
std::ifstream input(filename.c_str(), std::ios::in | std::ios::binary);
char c;
while (input.get(c)) {
// ...do something with c here...
}
}
Note: input >> c
discards leading whitespace, so you won’t normally use that when reading binary files.
How can I “reopen” std::cin
and std::cout
in binary mode?
This is implementation dependent. Check with your compiler’s documentation.
For example, suppose you want to do binary I/O using std::cin
and std::cout
.
Unfortunately there is no standard way to cause std::cin
, std::cout
, and/or std::cerr
to be opened in binary mode.
Closing the streams and attempting to reopen them in binary mode might have unexpected or undesirable results.
On systems where it makes a difference, the implementation might provide a way to make them binary streams, but you would have to check the implementation specifics to find out.
How can I write/read objects of my class to/from a data file?
Read the section on object serialization.
How can I send objects of my class to another computer (e.g., via a socket, TCP/IP, FTP, email, a wireless link, etc.)?
Read the section on object serialization.
Why can’t I open a file in a different directory such as "..\test.dat"
?
Because "\t"
is a tab character.
You should use forward slashes in your filenames, even on operating systems that use backslashes (DOS, Windows, OS/2, etc.). For example:
#include <iostream>
#include <fstream>
int main()
{
#if 1
std::ifstream file("../test.dat"); // RIGHT!
#else
std::ifstream file("..\test.dat"); // WRONG!
#endif
// ...
}
Remember, the backslash ("\"
) is used in string literals to create special characters: "\n"
is a newline, "\b"
is
a backspace, and "\t"
is a tab, "\a"
is an “alert”, "\v"
is a vertical-tab, etc. Therefore the file name
"\version\next\alpha\beta\test.dat"
is interpreted as a bunch of very funny characters. To be safe, use
"/version/next/alpha/beta/test.dat"
instead, even on systems that use a "\"
as the directory separator. This is
because the library routines on these operating systems handle "/"
and "\"
interchangeably.
Of course you could use "\\version\\next\\alpha\\beta\\test.dat"
, but that might hurt you (there’s a non-zero
chance you’ll forget one of the "\"
s, a rather subtle bug since most people don’t notice it) and it can’t help you
(there’s no benefit for using "\\"
over "/"
). Besides "/"
is more portable since it works on all flavors of Unix,
Plan 9, Inferno, all Windows, OS/2, etc., but "\\"
works only on a subset of that list. So "\\"
costs you something
and gains you nothing: use "/"
instead.
How can I tell (if a key, which key) was pressed before the user presses the ENTER key?
This is not a standard C艹 feature — C艹 doesn’t even require your system to have a keyboard!. That means every operating system and vendor does it somewhat differently.
Please read the documentation that came with your compiler for details on your particular installation.
(By the way, the process on UNIX typically has two steps: first set the terminal to single-character
mode, then use either select()
or poll()
to test if a key was
pressed. You might be able to adapt this code.)
How can I make it so keys pressed by users are not echoed on the screen?
This is not a standard C艹 feature — C艹 doesn’t even require your system to have a keyboard or a screen. That means every operating system and vendor does it somewhat differently.
Please read the documentation that came with your compiler for details on your particular installation.
How can I move the cursor around on the screen?
This is not a standard C艹 feature — C艹 doesn’t even require your system to have a screen. That means every operating system and vendor does it somewhat differently.
Please read the documentation that came with your compiler for details on your particular installation.
How can I clear the screen? Is there something like clrscr()
?
This is not a standard C艹 feature — C艹 doesn’t even require your system to have a screen. That means every operating system and vendor does it somewhat differently.
Please read the documentation that came with your compiler for details on your particular installation.
How can I change the colors on the screen?
This is not a standard C艹 feature — C艹 doesn’t even require your system to have a screen. That means every operating system and vendor does it somewhat differently.
Please read the documentation that came with your compiler for details on your particular installation.
How can I print a char
as a number? How can I print a char*
so the output shows the pointer’s numeric value?
Cast it.
C艹 streams do what most programmers expect when printing a char
. If you print a character, it prints as the actual
character, not the numeric value of the character:
#include <iostream>
#include <string>
void f()
{
char c = 'x';
std::string s = "Now is";
const char* t = "the time";
std::cout << c; // Prints a character, in this case, x
std::cout << 'y'; // Prints a character, in this case, y
std::cout << s[2]; // Prints a character, in this case, w
std::cout << t[2]; // Prints a character, in this case, e
}
C艹 streams also do the right thing when printing a char*
: it prints the string, which must be terminated by
'\0'
.
#include <iostream>
#include <string>
void f()
{
const char* s = "xyz";
std::cout << s; // Prints the string, in this case, xyz
std::cout << "pqr"; // Prints the string, in this case, pqr
}
These seem obvious only because they are intuitive, but in fact there is some pretty wonderful functionality going on in there. C艹 streams interpret the values of your chars into actual human readable symbols according to your current locale, plus they know that if you give them a character-pointer, you probably meant to print the C-like string. The only problem is when you do not want the code to behave this way.
Imagine you have a structure that stores peoples’ age as an unsigned char
. If you wanted to print that structure, it
would not make much sense to say that a person’s is 'A'
. Or if for some reason you wanted to print the address of that
age variable, the stream would start at that address and would interpret every subsequent byte (bytes of your struct or
class or even of the stack!) as a character, stopping finally when it reaches the first byte containing '\0'
.
// Variable 'age' stores the person's age
unsigned char age = 65;
// Our goal here is to print the person's age:
std::cout << age; // Whoops! Prints 'A', not the numeric age
// Our next goal is to print the age variable's location, that is, its address:
std::cout << &age; // Whoops! Prints garbage, and might crash
This is not what was desired. The simplest, and usually recommended, solution is to cast the char
or char*
to a
type your compiler does not interpret as characters, respectively an int
or a void*
:
// Variable 'age' stores the person's age
unsigned char age = 65;
// Our goal here is to print the person's age:
std::cout << static_cast<unsigned>(age); // Good: prints 65
// Our next goal is to print the age variable's location, that is, its address:
std::cout << static_cast<const void*>(&age); // Good: prints the variable's address
That works great for explicitly specified types, such as unsigned char
shown above. But if you are creating a
template, where the type unsigned char
above is simply known as some numeric type T
, you don’t want to assume the
proper numeric type is unsigned
or anything else. In this case, you want to convert your T
object to the proper
numeric type, whatever that is.
For example, your type T
might be anything from char
to int
to long
or long long
(if your compiler supports
that already). Or your type T
might even be an abstract numeric class that does not even provide a cast to any
built-in integer (think safe_integer
, ranged_integer
or big_num
classes, for example).
One way to handle this is through traits or template specialization, but there is a much simpler solution that works for
char
types without jeopardizing these other types. So long as type T
provides a unary +
operator with ordinary
semantics[*footnote], which is provided for all built-in numeric types, everything will work fine:
template <typename T>
void my_super_function(T x)
{
// ...
std::cout << +x << '\n'; // promotes x to a type printable as a number, regardless of type
// ...
}
Works like magic. The worst you have to worry about now is that it might be a bit cryptic to other developers. If you
are thinking to yourself, “Self, I should probably create a function called promote_to_printable_integer_type()
to
make my code self-documenting.” Unfortunately, C艹 currently lacks Type Inference, so writing such a function would
require code so complex it would probably bring more bugs than the (potential) ones you would prevent. So short term,
the best solution is to just bite the bullet, use operator+
and comment your code.
When your organization gets access to C艹11, you can start enjoying the convenience of type inference:
template <typename T>
auto promote_to_printable_integer_type(T i) -> decltype(+i)
{
return +i;
}
Without going into detail, the return type is “the same type as the type of +i”. It might look weird, but like most generic templates, what counts is the ease of use, not the beauty of the template definition itself. Here is a sample use:
void f()
{
unsigned char age = 65;
std::cout << promote_to_printable_integer_type(age); // Prints 65
}
template <typename T>
void g(T x)
{
// ...
std::cout << promote_to_printable_integer_type(x); // Works for any T that provides unary +
// ...
}
This answer will be updated due to C艹11 type inference. Watch this space for updates in the near future!!
[*footnote] If you are defining a class that represents a number, to provide a unary +
operator with canonical
semantics, create an operator+()
that simply returns *this
either by value or by reference-to-const.