A "Feild" Guide to Programming with C++
Introductory programming notes by Henry FeildChapter 3: Input/Output in C++
Important takeaways
- You can display (output) regular data to the console using
cout
, or error information viacerr
- Data that can be displayed include literals, variables, constants, and
the computed value of expressions (like
10*x
) - You can read data (input) from the user via the command line into
variables using
cin
Contents
Standard output
In most programs that you write, you'll want to display information to the user
of the program. This information might include literal values, variables,
constants, or any combination thereof (i.e., expressions). The simplest way to
display information to a user in C++ is to print it to the command line (we use
"print", "write", "display", and "output" interchangeably in programming). To
print to the command line (as opposed to a file), we use a character stream
called standard out (often abbreviated stdout). In
C++, we can access this stream using the cout
object.
The cout
object can be given an unlimited number of expressions,
each separated by two left angled brackets <<
. The evaluated
value of each expression is then printed to the CLI. Here's an example of a
program that displays the values of a couple of variables:
This should print: Name: Hank; age: 5
followed by a new line
(endl
is a constant that stores the new line character used for
your system; on most systems, that's "\n"). Let's
take a look at how it looks in a terminal, supposing we named this
outputExample.cpp
:
$ g++ outputExample.cpp -o outputExample $ ./outputExample Name: Hank; age: 5
If you need a tab, you can use the special escape character \t
.
This can be added directly in a string. For example,
cout << "Name: "<< name << ";\tage: " << age <<endl;
will add a
larger space between Name: Hank;
and age: 5
.
Formatting
It is often desirable to format your data in some automatic way. For example, say you want to write a program that will produce the following output:
Eggs: $1.50 Bread: $2.50 Milk: $3.00 ---------------------- Total: $7.00
Here, the first 16 characters are output should be the name of the item,
followed by colon, and then padded with spaces for the remaining characters.
cout
can be manipulated to do this using the iomanip
library. The example program below shows how we can produce the receipt above
in C++:
There's a lot more you can do with formatting output streams that I won't cover here, but you can learn about by poking around on this iomanip library page.
(Back to top)Standard error
Using cout
for output is perfect most of the time. However, if you
are printing an error message, the convention is to print it out using the
standard error stream, or stderr. This can be done
with the cerr
object, which you use exactly the same way as
cout
. In fact, in this class, we won't actually see a difference.
The reason it is helpful in general is that on a CLI, you can redirect stderr
and stdout separately. For example, you can direct all error messages to a log
file.
Here's an example of using both cout
and cerr
in a
program:
Standard input
So now we can output values so a user can see them, but how do we get input from
a user? We will use the standard input stream (stdin),
to read data from a user right from the command line. In
C++ is done via the cin
object. The cin
object looks
very similar to the two output objects, but we will use right angled brackets
and will be reading values from cin
into the variable on the right.
Here's how we can read in an age and name (separately) and then print them out:
Note that I added a space after the :
in the cout
statements on lines 9 and 12 and didn't bother with an
endl
—this is so that the prompt shows up on the same line as
where the user enters the information, and the extra space prevents the cursor
from starting directly adjacent to the :
. It's not required, but it
does make the prompt look nicer, so I strongly encourage you to do the same.
Here's what it looks like when I compile and run (supposing I've saved it to a
file named inputExample.cpp
), with my input in orange:
$ g++ inputExample.cpp -o inputExample $ ./inputExample Please enter your age: 5 Please enter your name: Hank Name: Hank; age: 5
In this example, we read the name and age in separately. The program will first
prompt the user for an age. The user can enter whatever they like, and then
press enter on the keyboard. This is important: only the first space-separated
value will be read into the variable to the right of >>
. If I
entered 15
, then age
would be set to the value 15. If
I entered 15 16 17
, age
would still be set to 15,
since it's the first of the three white-space separated numbers entered. This
has repercussions for strings with spaces: only the first word will be read in.
We'll learn how to read in whole lines in a bit.
We can also have users provide multiple pieces of information at once, separated by whitespace (spaces or new lines), and read them all in at once. Here's how we might read in the age and name of our user all at once:
Here's what it looks like when we run it (again, input in orange):
$ g++ inputExample2.cpp -o inputExample2 $ ./inputExample2 Please enter your age and name: 5 Hank Name: Hank; age: 5
A helpful way to think of the >>
operator is like asking
stdin to get the next thing from its input stream and store it in the variable to the
right. In the example above, the input stream looks like: 5 Hank
.
The first part of our cin
line looks like:
>> age
. This gets the next thing from the input stream,
5
, and assigns it to age
. When we do
>> name
, that reads the next thing, "Hank"
, and
assigns it to name
.
To read in a full line—everything up to the new line—we need to use
a special function called getline
. It works on arbitrary input
streams, not just cin
. It take two parameters: the stream to read
from (in our case, cin
), and the string variable to put the value
in. Note that you cannot read a line into a non-string variable. Here's an
example:
Supposing we save this into a file called getLineExample.cpp
and
run it, here's what we get:
$ g++ getLineExample.cpp -o getLineExample $ ./getLineExample Please enter your full name: Hank Feild Name: Hank Feild
If you use cin
prior to using getline
, be sure to
include the statement cin.ignore(1000, '\n');
to remove the
newline from the input stream (cin
leaves new lines in the stream
while getline
does not). For example, here's a version of our
earlier program that reads the user's age and name, but allows full names:
C style IO
C++ builds on the C programming language. Anything you can do in C, you can also
do in C++. In C, cin
and cout
do not exist. Instead,
to display text to the command line in C, we use printf
(the 'f' is
for 'formatted', as in 'print this formatted data'. To read, we use
scanf
.
printf(...)
printf
allows you to specify a format string and a list of zero or
more variables or literals whose values you would like to embed in the string.
The format string consists of a mix of text and placeholders for the variable
values you'd like to insert. There are different placeholders for different
types of data. For instance, to insert a variable of type int
, we
can use the place holder %d
('d' is for 'decimal integer'; that's
not decimal as in 'it has a decimal point', but rather the integer is base 10,
as opposed to binary, octal, or hexadecimal). Here's how we would print out an
age:
Note that we have a different include at the top. We don't need the
iostream
library because that's only for cout
and
cin
. We also don't need the using namespace std;
bit.
We DO need the stdio.h
library, though.
There are lots of other place holders besides %d
. The most useful
ones for us are %f
(for a floating point data, like
float
or double
), %c
(for
char
data), %s
(for string
data), and %%
(for a literal percent sign). You can see a full list
of formatting placeholders on this page.
For strings, things are a little strange. First, if you are not using
cout
or cin
, then be sure to include the
string
library and add the using namespace std;
bit
back in. Next, when you go to pass the string
variable to
printf
, you need to convert it from a C++ string to a C string. You
do that by appending .c_str()
directly after the variable name.
Here's an example:
You can have a format string with as many placeholders as you want, you just
need to supply the variables that go with the placeholders to
printf
as a comma separated list in the order they appear in the
format string. Here's an example:
You can do lots of other cool stuff with placeholders, such as specify the number of decimal places to display, specify a character width for a value and pad it with whitespace or 0s, and right/left align values. You can find more information about that here. Just to get an idea, though, here's an example that prints a the value "Distance" in a 20-character block, but right aligned, followed by a floating point number with two decimal places and left-aligned:
One word of warning; printf
is not type-safe, which means if you
mismatch the placeholders in the formatting string and the data you pass in,
your program will compile, but will crash when it runs. This is not the case
with cout
, which is considered safer to use (less buggy) than
printf
.
If you would like to format a string to store in a variable, consider
printf
's cousin, sprintf
. It works similarly, but
stores the formatted string in a character array. See
this page
for details.
scanf(...)
The input analog to printf
is a function called scanf
.
Rather than printing data in a particular format, it reads in data that matches
a particular format. Here's an example where we ask the user to enter some
information about themselves and then read that data in:
It is generally not good for reading from stdin, where
a user may input data in an incorrect format [1]. It's cousins
fscanf
(for reading from a file) and sscanf
(for
reading from a string) are generally more appropriate as you, the programmer,
can make more reasonable assumptions about files and strings than arbitrary
user input [1].