On this page

Input and Output

Every program so far had its numbers written into its text. To try another number you had to edit the program. In this lesson a program takes its values from outside while it runs, and prints its results in tidy lines: money with two decimal places, and tables in columns.

A program that waits

This program works out the cost of some tickets at 12 pounds each. The number of tickets is not in the program.

#include <iostream>

int main() {
    int tickets = 0;
    std::cin >> tickets;
    std::cout << tickets << " tickets cost " << tickets * 12 << " pounds.\n";
}
3
3 tickets cost 36 pounds.

The text a program receives while it runs is its input. std::cin is the input, as std::cout is the output.

Read std::cin >> tickets; as "take the next value from the input and store it in tickets". The arrows >> point from std::cin towards the variable, the direction the value travels. With std::cout the arrows point the other way.

When the program reaches that statement it waits until a value is available. Then it stores the value and goes on to the next statement. So the last line can use tickets, and it prints 36 because the input was 3.

The variable still gets a starting value, int tickets = 0;, as every variable should. The read then replaces it.

The value is stored as the type of the variable. The same statement with a double variable reads a number with a fraction.

#include <iostream>

int main() {
    double litres = 0.0;
    std::cin >> litres;
    std::cout << "Two bottles hold " << litres * 2 << " litres.\n";
}
1.75
Two bottles hold 3.5 litres.

A read into an int or a double expects a number. If the input holds something else there, such as the word three, the read fails and the variable holds nothing you can use. Module 4 shows how a program can find out that a read failed. Until then, give each program the kind of input it expects.

Where input comes from in the lab

On the lab page there is an Input box next to the editor. Type there what the program should receive, then press Run.

Everything in the box is available to the program from the start. The program still takes it one read at a time, in order, but it never has to wait for you to type.

Many programs print a question before they read. A short text that asks for input is called a prompt.

#include <iostream>

int main() {
    int tickets = 0;
    std::cout << "How many tickets? ";
    std::cin >> tickets;
    std::cout << "That is " << tickets * 12 << " pounds.\n";
}
3
How many tickets? That is 36 pounds.

Look at the output closely. There are two things to notice.

  • The 3 is not in it. The output panel shows only what the program printed. The input was read, not printed.
  • The answer is on the same line as the question. The prompt does not end with \n, so the next thing printed continues on that line. No line end comes from the input, because the input is not shown.

This is also how a program is tested by a machine. Each check in the lab puts its own text in the input, runs your program, and compares what it printed with the expected output, character by character. From this module on, most tasks say exactly what the output must be for a given input. A missing space or a missing \n counts as a difference.

Several values

One statement can read several values. Each >> takes the next one.

#include <iostream>

int main() {
    int hours = 0;
    int minutes = 0;
    std::cin >> hours >> minutes;
    std::cout << hours * 60 + minutes << " minutes\n";
}
2 15
135 minutes

The first >> stores 2 in hours. The second stores 15 in minutes.

How does >> know where one value stops and the next begins? Before it reads a value, >> skips any spaces and line ends in front of it. Then it takes characters for as long as they can belong to the value, and stops. So values may be separated by one space, by several, or by line ends. It makes no difference.

The next program reads the same two values with two statements, and its input has them on two lines, the second with spaces in front.

#include <iostream>

int main() {
    int hours = 0;
    int minutes = 0;
    std::cin >> hours;
    std::cin >> minutes;
    std::cout << hours * 60 + minutes << " minutes\n";
}
2
    15
135 minutes

std::cin >> hours >> minutes; and the two separate statements do the same thing. A read continues where the read before it stopped, whichever statement it is in.

The order of the reads is the order of the values in the input. If the program reads hours first, the first number in the input is the hours.

Words and whole lines

>> can fill a std::string as well. It follows the same rule: skip spaces and line ends, then take characters until the next space or line end. For text that means one word.

#include <iostream>
#include <string>

int main() {
    std::string city;
    std::cin >> city;
    std::cout << "City: " << city << "\n";
}
New York
City: New

The read stopped at the space. York was not thrown away. It is still in the input, and the next read would get it.

To read text that may contain spaces, read the whole line. That is a different call.

#include <iostream>
#include <string>

int main() {
    std::string city;
    std::getline(std::cin, city);
    std::cout << "City: " << city << "\n";
}
New York
City: New York

std::getline(std::cin, city); has two values in its parentheses: where to read from, and the variable to fill. It takes every character up to the end of the line, spaces included, and stores them in city. It also removes the line end from the input, but does not store it.

Statement What it reads
std::cin >> word; skips spaces and line ends, then one word
std::getline(std::cin, line); everything up to the end of the line, skipping nothing

The line end that stays behind

The two ways of reading do not mix as you might expect. This program reads a number, then a line.

#include <iostream>
#include <string>

int main() {
    int count = 0;
    std::string fruit;
    std::cin >> count;
    std::getline(std::cin, fruit);
    std::cout << count << " x <" << fruit << ">\n";
}
3
Red apples
3 x <>

fruit is empty. To see why, look at the input as the program gets it: one run of characters, in which every line end is a character too. Here each line end is written as ⏎.

3⏎Red apples⏎

std::cin >> count; takes the 3 and stops. It does not take the line end after it. What is left is this.

⏎Red apples⏎

std::getline reads up to the next line end, and the next line end is the very first character. So it reads a line with nothing in it. Red apples is still waiting, unread.

The repair is to skip the spaces and line ends before reading the line. std::ws does that when it is given to >>.

#include <iostream>
#include <string>

int main() {
    int count = 0;
    std::string fruit;
    std::cin >> count;
    std::getline(std::cin >> std::ws, fruit);
    std::cout << count << " x <" << fruit << ">\n";
}
3
Red apples
3 x <Red apples>

Read std::cin >> std::ws as "skip forward to the next character that is not a space or a line end". The getline then starts at the R.

The rule to remember: a getline that comes after a >> needs std::ws. A getline that comes first in the program, or straight after another getline, does not need it, because getline removes the line end it stopped at.

#include <iostream>
#include <string>

int main() {
    std::string fruit;
    std::string shop;
    std::getline(std::cin, fruit);
    std::getline(std::cin, shop);
    std::cout << fruit << " from " << shop << "\n";
}
Red apples
Hill Farm
Red apples from Hill Farm

Naming the headers you use

Until now the #include lines were part of the frame, given to you. From this module they are yours to write.

C++ itself is small. Most of what you use, std::cout and std::string included, comes from the standard library: ready-made code that is delivered with every C++ compiler. The library is divided into headers. A line such as #include <iostream> tells the compiler to read one header before it reads your program. After that, the names from that header are known.

Header What it gives you
<iostream> std::cin, std::cout, std::ws
<string> std::string, std::getline
<iomanip> std::setprecision, std::setw: the formatting in the next two sections

The std:: in front of each name says that the name belongs to the standard library.

A name whose header is missing is a name the compiler has never seen. This program has no #include line at all.

int main() {
    std::cout << "Hello\n";
}

The compiler answers with a message like this one.

your_program.cpp:2:5: error: use of undeclared identifier 'std'

It is the same kind of message as for a misspelt name. When the name in the message is spelt correctly and comes from the library, look at your #include lines first.

Three habits keep this from happening.

  • Write one #include line for each header the program uses, at the top, before int main().
  • Include <string> whenever the program has a std::string, even if it compiles without. One header sometimes brings in another, but which ones do so differs from compiler to compiler.
  • The course's own drawing calls come from #include "scimigo.h". Double quotes are for a file that belongs to the project; angle brackets < > are for the standard library.

Printing money

std::cout prints a double in the shortest form that shows its value, up to six digits. For money that is not what you want.

#include <iostream>

int main() {
    double price = 4.5;
    double third = 20.0 / 3;
    std::cout << price << "\n";
    std::cout << third << "\n";
}
4.5
6.66667

A price should read 4.50. Two names arrange that: std::fixed, which comes with <iostream>, and std::setprecision, which needs <iomanip>. They are sent to std::cout with << like a value, but they print nothing. They change how the values after them are printed.

#include <iomanip>
#include <iostream>

int main() {
    double price = 4.5;
    double third = 20.0 / 3;
    int count = 3;
    std::cout << std::fixed << std::setprecision(2);
    std::cout << price << "\n";
    std::cout << third << "\n";
    std::cout << count << "\n";
    std::cout << std::setprecision(1);
    std::cout << third << "\n";
}
4.50
6.67
3
6.7
  • std::fixed means: always print a fixed number of digits after the decimal point.
  • std::setprecision(2) says how many: two.

Notice four things in the output.

  • 4.5 became 4.50. Zeros are added to fill the two places.
  • 6.666... became 6.67. The value is rounded to the nearest, not cut off.
  • The int still prints as 3. The setting affects only numbers with a fraction.
  • The setting stays on. It was sent once, and both price and third were printed with two places. It lasts until the program sends another, as the last two lines show.

Only the printing changes. The variable third holds the same value throughout.

Columns

To line values up under one another, each value must take the same number of characters, whatever its length. std::setw(8), from <iomanip>, prints the next value in a space eight characters wide. The name is short for "set width". If the value is shorter than the width, spaces fill the rest.

#include <iomanip>
#include <iostream>

int main() {
    std::cout << std::setw(6) << 42 << "|\n";
    std::cout << std::setw(6) << 7 << 7 << "|\n";
}
    42|
     77|

In the first line, 42 is two characters, so four spaces come before it. The value sits at the right of its space.

The second line shows how std::setw differs from std::setprecision: it applies to one value only. The first 7 is printed six wide. The second 7 has no width, so it follows directly. Write std::setw again before every value that needs a width.

Numbers read best at the right of a column, and names at the left. std::left and std::right choose the side. They come with <iostream>. Unlike std::setw, these two stay on until the other one is sent.

#include <iomanip>
#include <iostream>

int main() {
    std::cout << std::fixed << std::setprecision(1);
    std::cout << std::left << std::setw(12) << "Leeds" << std::right << std::setw(7) << 272.5 << "\n";
    std::cout << std::left << std::setw(12) << "Southampton" << std::right << std::setw(7) << 112.0 << "\n";
    std::cout << std::left << std::setw(12) << "Bath" << std::right << std::setw(7) << 97.4 << "\n";
}
Leeds         272.5
Southampton   112.0
Bath           97.4

Each line does the same four things: switch to the left, print a name twelve wide, switch to the right, print a number seven wide. The names start under one another and the numbers end under one another.

Count the characters when a table looks wrong. Southampton has eleven letters, so one space fills its column of twelve. A value longer than its width is not cut short. It is printed in full and pushes the rest of the line to the right, so choose a width larger than the longest value.

Your turn

Now try it yourself

Predict what a program will do, run it, and step through it line by line. The checks tell you when your own code works.

Loading the lab…

In this lab

  1. Who waits for whom?

    This program prints a question, reads an age, and prints an answer. The Input box holds 20.

    Decide what the output panel will show, then press Run.

  2. Ask something else

    This is the program from the step before. Change it to ask for a year of birth and print the age the person reaches in 2026.

    With 2004 in the Input box, the output must be exactly:

    In which year were you born? In 2026 you turn 22.
    

    Rename the variable so that its name says what it now holds. The checks try other years as well.

  3. One line or two?

    This program reads two numbers with one statement and prints their product. The Input box holds 3 4 on one line.

  4. One word

    This program reads a name into a std::string and greets it. The Input box holds Ada Lovelace.

  5. The whole line

    The greeting program reads one word. Change the read so that the program greets the full name, however many words it has.

    With Ada Lovelace in the Input box, the output must be exactly:

    Hello, Ada Lovelace.
    
  6. The empty line

    This program reads an age with >>, then a name with std::getline. The square brackets in the last statement show exactly where the name starts and ends.

    The Input box holds two lines:

    36
    Ada Lovelace
    

    Answer the first two questions, then run it. For the third question, change the read of the name to std::getline(std::cin >> std::ws, name); and run again.

  7. Which header?

    This program should print 42 at the right of a space eight characters wide. std::setw does that; two steps from now you will use it yourself. For this step you need to know one thing about it: which header it comes from.

    Read the #include lines, decide, then press Run.

  8. Two decimal places

    This program prints the same double twice, the second time after std::fixed << std::setprecision(2) has been sent to the output. Then it prints one more number.

  9. Line up the columns

    This program prints three items and their prices with one space between name and price, so the prices are ragged. Run it and look.

    Use std::setw to make two columns: each name at the left of a column 10 wide, each price at the right of a column 8 wide. The output must be exactly:

    Tea           2.50
    Sandwich     11.75
    Cake          4.00
    

    Keep the three price variables. The checks run your program with other prices in them, and the columns must still line up.

  10. Rectangle calculator

    Write a program that reads two whole numbers, a width and then a height, and does two things.

    1. It draws a rectangle of that width and height, in "teal", with its top-left corner at (20, 20), on a canvas 600 wide and 400 high.
    2. It prints the rectangle's area and its perimeter (the distance all the way round) on two lines.

    With 120 80 in the Input box, the output must be exactly:

    Area: 9600
    Perimeter: 400
    

    The starter has the lines that drawing needs. Add the #include line for the header that std::cin and std::cout come from. The program prints no prompt.

  11. A receipt that asks

    Write a program that reads three things, in this order:

    1. a quantity, a whole number;
    2. a unit price, which may have a fraction;
    3. on the next line, the name of the item, which may contain spaces.

    It prints a receipt of three lines. Each line has a label at the left of a column 16 wide, and a number at the right of a column 8 wide. The first label is the item's name. Prices have two decimal places.

    With this in the Input box

    3 4.25
    Earl Grey tea
    

    the output must be exactly:

    Earl Grey tea       4.25
    Quantity               3
    Total              12.75
    

    The total is the unit price times the quantity. The program prints no prompt. The starter has no #include lines: write one for each header you use.

  12. Draw what was asked

    Write a program that reads four values: an x, a y, a radius (three whole numbers) and a colour (one word).

    On a canvas 600 wide and 400 high, it draws the circle with that centre, radius and colour. Then it prints one line that describes the circle.

    With 300 200 40 orange in the Input box, it draws an orange circle of radius 40 in the middle of the canvas, and the output must be exactly:

    orange circle at (300, 200), radius 40
    

    The starter has the lines that drawing needs. Add an #include line for each other header you use.

  13. Temperature

    Write a program that reads a temperature in degrees Celsius, which may have a fraction, and prints it in degrees Fahrenheit with one decimal place.

    Fahrenheit is Celsius times 9, divided by 5, plus 32.

    With 37 in the Input box, the output must be exactly:

    Fahrenheit: 98.6
    

    With 100 it is Fahrenheit: 212.0. The program prints no prompt.

  14. Change

    Write a program that reads an amount of money in cents, a whole number, and prints how to pay it with the fewest coins, using coins of 25, 10, 5 and 1 cent.

    Use as many 25 cent coins as fit, then as many 10 cent coins as fit in what is left, and so on.

    With 99 in the Input box, the output must be exactly:

    25 cent coins: 3
    10 cent coins: 2
    5 cent coins: 0
    1 cent coins: 4
    

    The program prints no prompt.

  15. Age, then name

    This program reads an age, then a name on the next line, then a town on the line after that. The Input box holds:

    36
    Ada Lovelace
    St Albans
    

    The output should be exactly:

    Ada Lovelace, 36, lives in St Albans.
    

    Run it and read what it prints instead. Then repair it. The name and the town may each have several words.

  16. Three rows

    Write a program that reads three pairs: a name (one word) and a score (a whole number), three times.

    It prints them as a table of three lines: each name at the left of a column 10 wide, each score at the right of a column 5 wide.

    With this in the Input box

    Ada 95
    Grace 100
    Linus 7
    

    the output must be exactly:

    Ada          95
    Grace       100
    Linus         7
    

    The program prints no prompt. You have no way yet to repeat statements, so write the reading and the printing out three times, with a variable for each name and each score.

  17. A story with blanks

    Write a program that asks for four words, one at a time, and then for one sentence, and prints a short story of your own that uses all five.

    For example, it might ask for a name, an animal, a colour and a number, and then for a piece of advice. Print a prompt before each read, so that someone using the program knows what to type.

    The Input box holds five lines to start you off. Change them to fit your own questions.

    Nothing checks this one. When the story reads well, go through the list below.