C++ I/O Quiz: cin, getline, fstream and filesystem Practice
Test your C++ I/O with 14 questions and three programs on stream state, getline after cin, open modes, stringstream reuse, binary records and std::filesystem.
- Course: C++ study plan
- Module: Streams and files
- Kind: Checkpoint — cleared at 70%
- Reading time: 25 min
- Runtime: Clang 18 · C++20
Checkpoint — Streams and files is the checkpoint that closes the Streams and files module: a graded quiz and whole-program exercises, passed at 70%.
Instructions
This checkpoint covers the whole module: stream state and recovery from a bad token, the character-level API, the reading-pattern catalogue, file streams and open modes, string streams with std::quoted and std::format, binary records and std::filesystem.
How it works. Fourteen questions and three programs. You need 70% on the questions and every program accepted to clear the module. You can retake it as often as you like; your best score counts.
Before you start, make sure you can answer these from memory:
- What does a stream's
operator booltest, and why caneof()be true after a successful read? - After
std::cin >> xfails onabc, what is inx, where isabc, and which two steps get the stream reading? - Why must
std::cin.ignore(...)followstd::cin >> nbefore the firststd::getline? - What does
std::ofstream out("f.txt")do to an existing file, and which mode adds to it instead? - Why does
in.str(next)on a usedstd::istringstreamstill fail, and what fixes it? - Why is
sizeofa struct of anint32_tand adouble16 rather than 12? - Why must a
directory_iteratorlisting be sorted before it is printed?
The three programs are a variable-field records reader, a std::format table with dynamic widths, and an inventory file written, measured, read back through a std::map and removed.
Common questions
After std::cin >> x fails on abc, what is in x?
x holds 0, because characters were examined and could not form a number; abc is still unread in the buffer; and failbit is set. Call std::cin.clear(), then discard the bad token with ignore or a string read, and the stream reads again.
What does opening an existing file with std::ofstream do?
The default mode truncates it to empty, so every run starts a fresh file. Open it with std::ios::app to keep the existing contents and add every write to the end.
Why must a directory_iterator listing be sorted?
std::filesystem::directory_iterator yields entries in an unspecified order — whatever the operating system returns — so the same directory can list differently on another machine. Collect the names into a vector and sort them before printing when the output must be deterministic.
Exercises
Records with a variable field count
Read lines until the input ends. Each non-blank line is a record <name> v1 v2 ... vk with k >= 0 integer values after the name. For each record print <name>: n=<k> sum=<s> max=<m>, or <name>: n=0 when there are no values. If any token after the name is not an integer, print line <L>: malformed instead, where L is the line's 1-based number counting every line, blank ones included. Skip blank lines silently. Finish with records=<good> bad=<malformed>.
Parse each line in its own std::istringstream; after the values loop stops, eof() on that stream tells a clean end from a bad token. Use long long.
Input: any number of lines. Output: one line per record or bad line, then the summary.
ada 3 5 9
bob
cy 7 x 2
dee -4 -6
prints
ada: n=3 sum=17 max=9
bob: n=0
line 4: malformed
dee: n=2 sum=-10 max=-4
records=3 bad=1A std::format table
Read an integer n, then n lines of <name> <qty> <price>. Print a table built with std::format and std::format_to only — no setw:
- the name column is left-aligned with a width of
max(4, longest name), passed as a dynamic width with{:<{}}; Qtyright-aligned in 5,Priceright-aligned in 9 with two decimals,Total(qty × price) right-aligned in 10 with two decimals;- a header row
Item,Qty,Price,Totalin the same fields; - a rule of
=as wide as the table (width + 24); - a last line with
Grand totalleft-aligned inwidth + 14and the grand total right in 10 with two decimals.
Build the whole text into one std::string with std::format_to(std::back_inserter(out), ...) and print it once.
Input: n, then n lines. Output: n + 3 lines.
2
pen 3 1.50
notebook 12 4.25
prints
Item Qty Price Total
pen 3 1.50 4.50
notebook 12 4.25 51.00
================================
Grand total 55.50Inventory file round trip
Read lines of <sku> <qty> (a one-word SKU and an integer quantity, possibly negative) until the input ends. Write each pair to inventory.txt as <sku> <qty> on its own line through a std::ofstream; close it and print bytes=<std::filesystem::file_size("inventory.txt")>. Then reopen the file with a std::ifstream, read the pairs back with >>, and add each quantity into a std::map<std::string, long long> keyed by SKU. Print <sku> <total> for every SKU in map order, then skus=<count> units=<sum of all totals>. Finally delete the file with std::filesystem::remove and print exists=yes or exists=no from std::filesystem::exists.
Input: any number of sku qty lines. Output: bytes=, the SKU lines, the summary, exists=.
bolt 10
nut 5
bolt 7
prints
bytes=21
bolt 17
nut 5
skus=2 units=22
exists=noIn this module: Streams and files
← Binary I/O and the filesystem · The undefined behaviour catalogue — what the compiler is allowed to assume →