C++ PROGRAMMING ยท 14 MIN STUDY

String streams, parsing, and input validation

Parse text using stringstream and validate input before using it in calculations.

Learning objectives

  • Use stringstream to parse formatted data from a string.
  • Distinguish parsing from reading a line.
  • Check extraction state and reject malformed input.
  • Understand why external data needs validation.

Prerequisites: strings, console input/output, and stream state. Review std::string, Input and output, and File I/O first.

What is a string stream?

A std::stringstream is a stream that reads from and writes to a string buffer. It lets you use familiar stream extraction and insertion operations when the source or destination is a string rather than the terminal or a file.

C++17
#include <iostream>
#include <sstream>
#include <string>

int main() {
    std::string record{"42 87.5"};
    std::istringstream input{record};
    int id{};
    double score{};
    if (input >> id >> score) {
        std::cout << id << ": " << score << '\n';
    } else {
        std::cerr << "Invalid record\n";
    }
}

std::istringstream is for input from a string. std::ostringstream is for output to a string. std::stringstream supports both directions.

Validate the entire record

Successful extraction of the expected fields does not necessarily mean the whole input is valid. If trailing non-whitespace text is not allowed, check for extra content after reading the expected values.

std::istringstream input{"42 87.5 extra"};
int id{};
double score{};
if ((input >> id >> score) && !(input >> std::ws).eof()) {
    // extra non-whitespace data remains: reject the record
}

Validation rules depend on your data format. A CSV file, for example, needs delimiter-aware parsing; splitting on whitespace is not a correct CSV parser.

Input validation strategy

  1. Read a complete line when the format is line-based.
  2. Parse the expected fields.
  3. Check that each conversion succeeded.
  4. Check ranges and relationships between fields.
  5. Reject or report extra malformed data according to the format contract.

Common mistakes

  • Assuming successful extraction validates every character in the record.
  • Using whitespace extraction when spaces are part of a field.
  • Parsing CSV with a simple stringstream whitespace split.
  • Ignoring stream failure and using variables that were not successfully populated.

Practice

  1. Parse a line containing an integer ID and a double score.
  2. Reject a line with a missing score.
  3. Reject extra trailing text if the format allows exactly two fields.
  4. Explain why a real CSV parser must handle quoted fields and commas inside quotes.

Practice solutions

Show worked solutions
  1. Construct an std::istringstream from the line, then extract int id and double score. Check the stream after both extractions before using either value.
  2. If the line contains only an ID, the second extraction fails. Test if (!(input >> id >> score)) and reject the record rather than using an uninitialized or stale score.
  3. After reading the expected fields, consume permitted whitespace with input >> std::ws;. Then reject the record if !input.eof(); remaining non-whitespace text is extra data.
  4. CSV allows quoted fields, escaped quote characters, delimiters inside quoted fields, and sometimes embedded line breaks. A whitespace-based stringstream extraction does not implement those rules; use a CSV parser or write a parser that follows the full format specification.

Check your understanding

Does reading two expected fields prove that a record contains only two fields?

Answer: No. Check for remaining non-whitespace content if the format forbids extra fields.

Summary

String streams let you parse text with stream operations. Always check extraction success and validate the full record against its format, not just the first values.

References