Menu

C++ String Streams: stringstream Parsing & Building

How to use std::stringstream, istringstream, and ostringstream to parse text, split strings on whitespace, convert between strings and numbers, and build formatted strings in memory.

This page includes runnable editors - edit, run, and see output instantly.

A Stream That Lives in a String

You already know cin and cout - streams wired to the keyboard and the screen. A string stream is the same idea, except the data lives in an in-memory std::string instead. You write into it with << and pull values out with >>, exactly like the console streams, but nothing touches the terminal.

That single idea solves two everyday problems: parsing text apart into typed values, and building a formatted string out of mixed pieces. Everything lives in the <sstream> header and comes in three flavors:

  • istringstream - read-only, for parsing input.
  • ostringstream - write-only, for building output.
  • stringstream - both directions.

ss.str() returns everything written so far as a plain string. The << operators did the same int-to-text formatting that cout does - you just captured the result instead of printing it.

Parsing: Pull Typed Values Out

The real power shows up with >>. Feed a stream some text and extraction converts each token into the type you ask for, skipping whitespace between them. This is the clean way to break one line into several typed fields:

Each >> reads up to the next whitespace and converts: "Ada" into a string, "36" into an int, "5.5" into a double. Note istringstream here - the input-only type makes it clear you're only parsing.

Converting Strings to Numbers (Safely)

A frequent job is turning a single string like "42" into an int. A stringstream does it, and tells you whether the text was actually a valid number - which atoi never does:

Here ss >> value reads 123, stops at the a, and succeeds - so always validate the whole string if that matters. A robust check is to read the number and then confirm nothing meaningful is left over. For straightforward single-value conversions, std::stoi, std::stod, and friends are shorter; reach for stringstream when one string carries several mixed values.

Splitting a String on a Delimiter

Splitting text is the most-Googled string-stream task. Combine a stream with std::getline, which can read up to any delimiter character, not just a newline:

The while (getline(...)) pattern loops until the stream runs dry, because getline returns the stream and the stream tests as false once there's nothing left. Each token is pushed onto a vector, the natural place to collect a variable number of split pieces. Drop the third argument and you split on whitespace tokens with >> instead - pick whichever delimiter your data uses.

Building Strings in Memory

Going the other way, ostringstream assembles a formatted string without sprintf's buffer-overflow risk or fragile manual concatenation. It's perfect for log lines, file names, or messages stitched from numbers and text:

All the <iomanip> formatting you'd use with cout - setw, setfill, setprecision, hex - works identically on a string stream, so you get padded, fixed-width, or hex output captured straight into a string.

The Gotcha: Reset Before Reusing

The trap that bites everyone is reusing a stream without resetting it. Once a stream reaches the end of its data, its eof and fail flags latch on, and every later >> silently does nothing - no error, just stale values:

stringstream ss("10");
int a, b;
ss >> a;            // a = 10, stream now at end -> eof flag set
ss.str("20");       // load new text...
ss >> b;            // FAILS SILENTLY - error flags are still set, b is unchanged

You must clear the error state and the contents. The right order is clear() first, then str():

Two related mistakes: ss.clear() resets the flags but does not empty the buffer (use ss.str("") for that), and a stringstream you keep appending to with << will keep growing - create a fresh one inside a loop rather than reusing a dirty one for each iteration.

Next: Arrays

String streams gave you a clean way to turn text into typed values and back again - often a whole list of them, like the vector you filled while splitting CSV. To store and index fixed collections of those values, you need the most fundamental container in the language. Next we'll cover arrays: how to declare them, index into them, loop over them, and sidestep the out-of-bounds access that causes so much undefined behavior in C++.

Frequently Asked Questions

What is a stringstream in C++?

A std::stringstream is a stream backed by a string instead of the keyboard or a file. You write to it with << and read from it with >>, just like cout and cin, which makes it the standard tool for parsing text and building strings in memory. It lives in the <sstream> header.

How do you convert a string to an int in C++ with stringstream?

Put the text into a stream and extract into a number: stringstream ss("42"); int n; ss >> n;. Check if (ss) (or if (ss >> n)) to confirm the conversion actually succeeded. For simple cases std::stoi is shorter, but stringstream shines when one string holds several mixed values.

Why do I need to call clear() on a stringstream?

Once a stream hits the end of its data, its eof/fail bits stick and every further >> quietly does nothing. If you reuse the same stringstream with new content, call ss.clear() to reset those error flags, then ss.str(newText) to load fresh data - otherwise reads silently fail.

Coddy programming languages illustration

Learn to code with Coddy

GET STARTED