C/C++ Arena

Step 1 of 6

Parsing with istringstream

std::cin reads from the keyboard (or piped input). But a lot of text you need to parse is already sitting in a std::string: a line you just read, a command, a config value. A std::istringstream (from <sstream>) wraps a string so you can read from it exactly like std::cin.

#include <iostream>
#include <sstream>
#include <string>

int main() {
    std::string line;
    while (std::getline(std::cin, line)) {
        std::istringstream in(line);
        std::string item;
        int qty;
        double price;
        if (!(in >> item >> qty >> price)) {
            std::cout << "skipping bad line: [" << line << "]\n";
            continue;
        }
        std::cout << item << " costs " << qty * price << "\n";
    }
}
pen 3 1.5
oops
book 2 12
pen costs 4.5
skipping bad line: [oops]
book costs 24

Why read a line first?

std::cin >> x skips over newlines, so it can't tell where one line ends and the next begins. When the line structure matters (one record per line, a variable number of values per line), use this two-step pattern:

  1. std::getline(std::cin, line) reads one whole line into a string (without the newline).
  2. A fresh std::istringstream in(line) parses just that line. When it runs out, you know the line is done.

Reading until the data runs out

A stream converts to false once a read fails. So this loop reads every number on a line, however many there are, including zero:

int x;
while (in >> x) { /* use x */ }

The loop also stops at something that isn't a number, like the word abc.

Common mistakes

Your turn: each input line holds a player name followed by some round scores (possibly none). For each line print NAME TOTAL.

Next: Formatting tables with iomanip