Kodewick
Lesson 3 of 30Contents

Input and output formatting

Lesson 3 of 30 · Part 1 · Getting started · about 15 minutes

So far every value has been written into the program. std::cin is the input stream: it waits for the user to type something, then puts the value into a variable. Press Run and type a number; the output on the page shows what happens when someone types 25 (what they type isn't shown).

main.cpp
1#include <iostream>2 3int main() {4    int age = 0;5    std::cout << "How old are you?\n";6    std::cin >> age;7    std::cout << "You are " << age << '\n';8    return 0;9}
Output
How old are you?
You are 25

In std::cin >> age the arrows point at the variable: the value flows from cin into age. cout uses <<, pointing at cout, so values flow out. >> looks at the variable's type: age is an int, so it reads a whole number.

Reading several values

Like cout, >> can be chained to fill several variables in order. They don't need to have the same type:

main.cpp
1#include <iostream>2 3int main() {4    int count = 0;5    double price = 0;6    std::cout << "How many, and at what price?\n";7    std::cin >> count >> price;8    std::cout << "That's $" << count * price << " in all\n";9    return 0;10}
Output
How many, and at what price?
That's $59.7 in all

The user can type 3 19.9 and press Enter, or 3, Enter, 19.9, Enter: >> skips spaces and new lines before it reads the next value.

It stops at a space

>> can read a std::string too. But it reads only one "word": it skips leading spaces and stops at the next space or new line. Say the user types Ana Lee:

main.cpp
1#include <iostream>2#include <string>3 4int main() {5    std::string name;6    std::cout << "What's your name?\n";7    std::cin >> name;8    std::cout << "Hello, " << name << "!\n";9    return 0;10}
Output
What's your name?
Hello, Ana!

It only got Ana. The Lee after the space is still waiting in the input for the next read.

getline reads a whole line

To read spaces too, use std::getline(std::cin, s): it puts the rest of the line into s, up to the new line (and leaves the new line out).

main.cpp
1#include <iostream>2#include <string>3 4int main() {5    std::string name;6    std::cout << "What's your name?\n";7    std::getline(std::cin, name);8    std::cout << "Hello, " << name << "!\n";9    return 0;10}
Output
What's your name?
Hello, Ana Lee!

getline lives in <string> too. Use it for names, addresses and sentences; use >> for numbers.

getline after cin >>

Reading a number with >> and then a line with getline runs into a well-known problem. The user types 30, Enter, then Ana Lee, Enter:

main.cpp
1#include <iostream>2#include <string>3 4int main() {5    int age = 0;6    std::string name;7    std::cin >> age;8    std::getline(std::cin, name);9    std::cout << "Age: " << age << '\n';10    std::cout << "Name: " << name << '\n';11    return 0;12}
Output
Age: 30
Name: 

The name is empty. >> stopped right after 30, so the new line after it is still in the input. getline meets it straight away, decides the line is over, and reads an empty line.

The fix: put std::cin.ignore(); before getline (ignore is something cin itself can do, so it comes after std::cin.). It throws away one character, the leftover new line:

main.cpp
1#include <iostream>2#include <string>3 4int main() {5    int age = 0;6    std::string name;7    std::cin >> age;8    std::cin.ignore();9    std::getline(std::cin, name);10    std::cout << "Age: " << age << '\n';11    std::cout << "Name: " << name << '\n';12    return 0;13}
Output
Age: 30
Name: Ana Lee

Note: ignore() throws away just one character. If the user typed extra spaces after 30, it won't be enough. For now, just remember where this trap is.

Decimal places

You can control how output looks, too; the tools are in <iomanip>. On its own, std::setprecision(n) sets how many digits are shown in all. Only with std::fixed in front does it mean "digits after the decimal point":

main.cpp
1#include <iostream>2#include <iomanip>3 4int main() {5    double average = 86.4567;6    std::cout << average << '\n';7    std::cout << std::setprecision(2) << average << '\n';8    std::cout << std::fixed << average << '\n';9    std::cout << 5.0 << '\n';10    return 0;11}
Output
86.4567
86
86.46
5.00

The second line has just two digits: 86. The third, with std::fixed, has two decimal places, 86.46 (rounded). The last line shows that both settings stay in effect: every double after them gets two decimal places, so even 5.0 shows as 5.00. For prices and averages, write std::fixed << std::setprecision(2) once.

Lining up with setw

std::setw(n) makes the next value take at least n places, padding with spaces on the left, so numbers line up on the right:

main.cpp
1#include <iostream>2#include <iomanip>3 4int main() {5    std::cout << "Tea" << std::setw(6) << 3 << '\n';6    std::cout << "Jam" << std::setw(6) << 12 << '\n';7    std::cout << "Egg" << std::setw(6) << 120 << '\n';8    return 0;9}
Output
Tea     3
Jam    12
Egg   120

Unlike fixed, setw applies only to the one value right after it, so write it before each value you want lined up. It counts bytes: an English letter is one, but characters such as Chinese ones take more, so it won't line those up.

Guess first

How many spaces are there between [ and 42?

1#include <iostream>2#include <iomanip>3 4int main() {5    std::cout << "[" << std::setw(5) << 42 << "]\n";6    return 0;7}

Practice

Write the code, then press Check. A hint costs nothing; the answer is there when you need it. Nobody types anything during a check, so the "input" values are already in variables.

Exercise 1

A price with two decimals

Make the program show Price: 3.50.

It should print
Price: 3.50
exercise1.cpp
1#include <iostream>2#include <iomanip>3 4int main() {5    double price = 3.5;6    std::cout << "Price: " << price << '\n';7    return 0;8}
Output
Press Run or Ctrl+Enter
Exercise 2

Scores lined up

Use std::setw(5) to line the three scores up on the right, as below (each score takes 5 places).

It should print
Math   95
Chem    8
Arts  100
exercise2.cpp
1#include <iostream>2#include <iomanip>3 4int main() {5    int math = 95;6    int chem = 8;7    int art = 100;8 9    return 0;10}
Output
Press Run or Ctrl+Enter
Exercise 3

Fix it: missing decimals

This program should show Total: 12.00, but it shows Total: 12. Fix it.

It should print
Total: 12.00
exercise3.cpp
1#include <iostream>2#include <iomanip>3 4int main() {5    double total = 4 * 3.0;6    std::cout << std::setprecision(2);7    std::cout << "Total: " << total << '\n';8    return 0;9}
Output
Press Run or Ctrl+Enter

What you learned

  • std::cin >> x reads a value into x, the way x's type says; >> can be chained to read several.
  • >> skips spaces and new lines; for a std::string it reads one word and stops at a space.
  • std::getline(std::cin, s) reads a whole line, spaces and all.
  • getline after cin >> reads the leftover new line; throw it away first with std::cin.ignore();.
  • <iomanip>: std::fixed << std::setprecision(2) shows two decimal places, and stays in effect.
  • std::setw(n) makes the next value take at least n places, lined up on the right; it covers one value.