Input & Output (cin & cout)
Reviewed & published by Brayan K
Programs that talk to people need to read input and print output. In this lesson you'll master std::cin >> for reading, std::getline for whole lines, std::cout << for printing, formatting with <iomanip>, and how to recover gracefully when the user types something unexpected.
Part of the free C++ course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.
What You'll Learn
- Read words and numbers with cin >>
- Read whole lines (spaces included) with getline
- Fix the classic cin >> then getline buffer bug
- Format numbers with fixed, setprecision and setw
- Choose endl vs '\n' and understand flushing
- Detect and recover from invalid input with clear/ignore
💡 Real-World Analogy
Think of cin as a conveyor belt carrying everything the user typed, separated by gaps (whitespace). The >> operator is a robot arm that grabs one item off the belt and stops at the first gap. getline is a bigger scoop that takes the entire row up to the next newline. The catch: when you switch from the small arm to the big scoop, a leftover "end of row" marker is still on the belt — and the scoop grabs that first unless you sweep it off with cin.ignore().
1. Reading with cin >>
The extraction operator >> reads one whitespace-separated token and converts it to match the variable's type. A word goes into a string, a number into an int or double. You can chain several reads on one line.
#include <iostream>
#include <string>
using namespace std;
int main() {
string name;
int age;
cout << "What's your name? ";
cin >> name; // reads ONE word (stops at whitespace)
cout << "How old are you? ";
cin >> age; // reads a whole number
cout << "Hello " << name << ", next year you'll be "
<< age + 1 << "!\n";
// If you type: Alice 30
// Output: Hello Alice, next year you'll be 31!
return 0;
}2. Reading Whole Lines with getline
Because >> stops at the first space, it can't read "Ada Lovelace" into one string. getline(cin, line) reads everything up to the Enter key — spaces and all — which is what you want for names, addresses, and sentences.
#include <iostream>
#include <string>
using namespace std;
int main() {
cout << "Enter your full name: ";
string fullName;
getline(cin, fullName); // reads the WHOLE line, spaces included
cout << "Enter a sentence: ";
string sentence;
getline(cin, sentence);
cout << "Name: " << fullName << '\n';
cout << "You said: " << sentence << '\n';
// Input: Ada Lovelace
// I love C++
// Output: Name: Ada Lovelace
// You said: I love C++
return 0;
}3. The cin >> then getline Trap
This is the single most common beginner I/O bug. After cin >> qty reads the number, the newline you pressed stays in the buffer. The next getline grabs that empty leftover and returns immediately. The fix is one line: cin.ignore(...) to discard the stray newline before calling getline.
#include <iostream>
#include <string>
#include <limits>
using namespace std;
int main() {
int qty;
cout << "How many items? ";
cin >> qty; // leaves the newline in the buffer!
// Without this line, the getline below would read an empty string.
cin.ignore(numeric_limits<streamsize>::max(), '\n');
string note;
cout << "Add a note: ";
getline(cin, note); // now this reads the real line
cout << "Order: " << qty << " items. Note: " << note << '\n';
// Input: 3
// gift wrap please
// Output: Order: 3 items. Note: gift wrap please
return 0;
}4. Formatting Output with <iomanip>
By default cout prints up to 6 significant digits and trims trailing zeros, which looks wrong for money. Combine std::fixed with std::setprecision(n) for exactly n decimal places, and use std::setw(n) to pad a value into a fixed-width column for neat tables.
#include <iostream>
#include <iomanip> // setprecision, setw, fixed
using namespace std;
int main() {
double price = 19.5;
// Default: up to 6 significant digits.
cout << "default: " << price << '\n'; // 19.5
// fixed + setprecision(2): exactly two decimal places.
cout << fixed << setprecision(2);
cout << "money: $" << price << '\n'; // $19.50
// setw(n) pads a field to n characters wide (right-aligned).
cout << "right: |" << setw(8) << "hi" << "|\n"; // | hi|
cout << left;
cout << "left: |" << setw(8) << "hi" << "|\n"; // |hi |
return 0;
}
// ✅ Expected output:
// default: 19.5
// money: $19.50
// right: | hi|
// left: |hi |5. Handling Bad Input
If the user types letters when you expect a number, cin enters a failed state and stops reading. A robust program checks the result of cin >>, calls cin.clear() to reset the error, and cin.ignore(...) to throw away the offending input before trying again.
#include <iostream>
#include <limits>
using namespace std;
int main() {
int n;
cout << "Enter a number: ";
// cin >> returns the stream; in an if it tests true on success.
while (!(cin >> n)) {
cin.clear(); // clear the failed (error) state
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // drop bad input
cout << "That's not a number. Try again: ";
}
cout << "Thanks! You entered " << n << '\n';
// Input: hello then 42
// Output: That's not a number. Try again: Thanks! You entered 42
return 0;
}Your turn. Complete the two reads below:
#include <iostream>
#include <string>
using namespace std;
int main() {
// 🎯 YOUR TURN — complete the two reads.
cout << "City: ";
string city;
___; // 👉 read a SINGLE word into city (cin >> city)
cout << "Population: ";
long long pop;
___; // 👉 read a whole number into pop (cin >> pop)
cout << city << " has " << pop << " people.\n";
// Input: Tokyo 14000000
// Output: Tokyo has 14000000 people.
return 0;
}🧩 Reorder Challenge
This program should read an age (number) and then a full name (line). The lines are scrambled — order them so the getline works correctly.
A. getline(cin, name);
B. cin >> age;
C. cin.ignore();
D. int age; string name;
E. cout << name << " is " << age << '\n';
F. return 0;D. int age; string name;
B. cin >> age;
C. cin.ignore();
A. getline(cin, name);
E. cout << name << " is " << age << '\n';
F. return 0;Why: declare the variables first, then read the number with >>. The crucial step is cin.ignore() between the >> and the getline — it removes the leftover newline. Without it (line C in the wrong place), getline would read an empty string. Finally print, then return.
🧠 Quick Recall
Predict the output before revealing each answer.
// input: "Grace Hopper" then cin >> word; cout << word;
Grace — >> stops at the first space, so only the first word is read. The rest ("Hopper") stays on the input buffer.
cout << fixed << setprecision(2) << 7.0;
7.00 — fixed with setprecision(2) forces exactly two decimal places.
// input: "abc" into an int n; what is the state of cin afterward?
cin enters a failed (fail) state; n is set to 0 and all further extractions fail until you call cin.clear() and cin.ignore(...).
Pro Tips
- 💡 Prefer '\n' over endl: endl flushes the buffer every time, which is slower in loops.
- 💡 Always cin.ignore() after a >> read if a getline follows.
- 💡 Check your reads: if (cin >> n) { ... } lets you handle bad input instead of crashing onward silently.
- 💡 Set formatting once: manipulators like fixed are "sticky" — they stay in effect until changed.
Common Errors (and the fix)
- Empty getline after >>: the leftover newline is read. Add cin.ignore(...) in between.
- Half a sentence captured: you used cin >> s for multi-word text. Use getline instead.
- setprecision without fixed: setprecision(2) alone counts significant digits, not decimals. Add fixed for money.
- Infinite loop on bad input: forgetting cin.clear() leaves the stream failed, so every later read fails instantly.
📋 Quick Reference
| Operation | Description | Note |
|---|---|---|
| cin >> x; | read one whitespace-separated token | stops at the first space/newline |
| getline(cin, line); | read a whole line | includes spaces, stops at Enter |
| cin.ignore(n, '\n'); | discard leftover input | use between >> and a following getline |
| cin.clear(); | reset a failed stream | after a bad read, before retrying |
| if (cin >> n) { ... } | test a read for success | false when extraction fails |
| cout << x; | print a value | chain with more << |
| '\n' | newline | preferred over endl (no flush) |
| endl | newline + flush | slower; use only when a flush is needed |
| fixed | fixed-point notation | from <iomanip>; pairs with setprecision |
| setprecision(2) | 2 decimals (with fixed) | significant digits without fixed |
| setw(8) | pad field to 8 chars | applies to the next value only |
| left / right | field alignment | sticky until changed |
| #include <iomanip> | formatting manipulators | needed for setprecision / setw |
Mini-Challenge: Receipt Printer
Read an item, a price, and a quantity, then print a formatted receipt with the total to two decimal places. Match the expected output in the comments.
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
int main() {
// 🎯 MINI-CHALLENGE: receipt printer
// 1. Ask for an item name (a single word) and read it with cin >>.
// 2. Ask for a unit price (double) and a quantity (int).
// 3. Print a receipt with the total formatted to 2 decimal places
// using fixed << setprecision(2).
//
// Example — input: Coffee 3.5 4
// Expected output:
// Coffee x4 @ $3.50 = $14.00
// your code here
return 0;
}🎉 Lesson Complete
- ✅ cin >> reads one whitespace-separated token; getline reads a whole line
- ✅ Call cin.ignore(...) between a >> read and a following getline
- ✅ fixed + setprecision(n) control decimals; setw(n) pads columns
- ✅ Prefer '\n' to endl except when you need a flush
- ✅ Validate input with if (cin >> x) and recover with clear() + ignore()
Practice quiz
If the input is "Grace Hopper" and you do cin >> word; cout << word; what prints?
- Grace Hopper
- Hopper
- Grace
- An empty string
Answer: Grace. The >> operator stops at the first whitespace, so it reads only the first token, 'Grace'. The rest stays on the input buffer.
Which function reads a whole line, including spaces, up to the Enter key?
- getline(cin, line)
- cin >> line
- cin.read(line)
- cin.get(line)
Answer: getline(cin, line). getline(cin, line) reads everything up to (but not including) the newline, so it captures multi-word input like 'Ada Lovelace'.
Why might a getline right after cin >> age return an empty string?
- getline is broken
- age was negative
- You must call cin.flush()
- The leftover newline from the >> read is still in the buffer and getline reads it
Answer: The leftover newline from the >> read is still in the buffer and getline reads it. After cin >> age, the newline you pressed stays in the buffer. The next getline reads that leftover newline. Fix it with cin.ignore() in between.
What does cout << fixed << setprecision(2) << 7.0; print?
- 7
- 7.00
- 7.0
- 7.000
Answer: 7.00. fixed with setprecision(2) forces exactly two decimal places, so 7.0 prints as 7.00.
Without 'fixed', what does setprecision(n) count?
- Total significant digits
- Decimal places
- Field width
- Trailing zeros
Answer: Total significant digits. setprecision alone counts total significant digits. You need std::fixed together with it to get exactly n decimal places.
What is the main difference between endl and ' '?
- endl prints two newlines
- ' ' flushes but endl does not
- endl also flushes the output buffer, which has a small cost
- They are identical in every way
Answer: endl also flushes the output buffer, which has a small cost. Both move to a new line, but endl also flushes the buffer immediately. Prefer ' ' for ordinary output; use endl only when you need a flush.
What does std::setw(8) do?
- Sets 8 decimal places
- Pads the next value to a field 8 characters wide
- Skips 8 characters of input
- Repeats output 8 times
Answer: Pads the next value to a field 8 characters wide. setw(n) pads the next value into a field n characters wide (right-aligned by default). It applies only to the next value.
If the user types letters when cin expects an int, what happens?
- The program crashes
- The int becomes a random value
- cin reads the letters as ASCII codes
- cin enters a failed state and all further reads fail until you clear it
Answer: cin enters a failed state and all further reads fail until you clear it. Extraction fails, cin enters a failed state (the variable is set to 0 since C++11), and further reads fail until cin.clear() and cin.ignore().
Which two calls recover a failed cin so you can re-prompt?
- cin.reset() and cin.flush()
- cin.clear() and cin.ignore(...)
- cin.good() and cin.eof()
- cin.open() and cin.close()
Answer: cin.clear() and cin.ignore(...). cin.clear() resets the error state, then cin.ignore(...) discards the bad input still sitting in the buffer before you try again.
Which header do you include for setprecision, fixed, and setw?
- <iostream>
- <string>
- <iomanip>
- <cstdio>
Answer: <iomanip>. The formatting manipulators setprecision, fixed, setw, left, and right live in <iomanip>.
Continue this course
- Previous: Data Types
- Next: Operators — Arithmetic, comparison, logical, and bitwise operators explained
- Quick reference: C++ cheat sheet › Basics
Frequently asked questions
Why does cin >> name only read one word when I type a full sentence?
The >> operator splits input on whitespace, so it stops at the first space, tab, or newline. To read a whole line including spaces, use std::getline(cin, line) instead. That reads everything up to (but not including) the Enter key.
I mixed cin >> age and getline and the getline came back empty — why?
After cin >> age reads the number, the newline you pressed is still sitting in the input buffer. The next getline reads that leftover newline and returns an empty string. Fix it by calling cin.ignore() (or cin.ignore(10000, ' ')) after the >> read to discard the stray newline.
What is the difference between endl and ' '?
Both move to a new line, but endl also flushes the output buffer — it forces everything to be written to the screen immediately. That flush has a small cost. For ordinary output prefer ' '; use endl only when you specifically need the buffer flushed, for example right before a long computation.
How do I control how many decimal places cout prints?
Include <iomanip> and use std::fixed together with std::setprecision(n). For example cout << fixed << setprecision(2) << price prints exactly two decimal places. Without fixed, setprecision counts total significant digits instead of decimal places.
What happens if the user types letters when my program expects a number?
The extraction fails, cin enters a failed state, and the variable is left unchanged (set to 0 since C++11). All further reads silently fail until you clear the error with cin.clear() and discard the bad input with cin.ignore(). Robust programs check the result of cin >> and recover from failures.