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 task

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

Challenge 2

Each line holds a player name followed by some round scores (maybe none). Print the name and the best score, or the name and - if there are no scores. Parse each line with a std::istringstream.

Challenge 3

Each line is a CSV row name,kills,deaths. Print name diff with the kills minus the deaths. Skip lines that don't have all three fields as numbers. Read the name up to the comma with std::getline(in, name, ','), then the numbers with >>, reading each comma into a char.

Next: Formatting tables with iomanip