Question

How to Clear a std::stringstream in C++

cppstringstream

Question

How can I completely clear a std::stringstream in C++ so that it no longer contains its previous text and can be reused?

I tried the following, but neither achieves the result I want:

std::stringstream m;
m.empty();
m.clear();

Short Answer

By the end of this page, you will know that a std::stringstream has both stored text and stream state flags. You will learn how to reset both correctly with str("") and clear(), and when each operation is necessary.

Concept

A std::stringstream is a stream backed by an internal std::string. It is useful when you want to write values into text, read values back from text, or convert between text and other types.

There are two different things that may need resetting:

  1. The buffered text — the characters currently stored in the stream.
  2. The stream state — flags such as eofbit and failbit that record whether reading succeeded.

Use these operations for their separate jobs:

stream.str(""); // Remove the stored characters.
stream.clear(); // Clear error/end-of-file state flags.

To fully reset a stream for reuse, use both:

stream.str("");
stream.clear();

clear() does not erase text. It only resets state flags. This matters because a stream that reached the end of its input, or failed to parse a value, may refuse later input operations until its error state is cleared.

std::stringstream does not have an empty() member function. To check whether its current text is empty, retrieve the string first with str() and then call empty() on that string.

Mental Model

Think of a std::stringstream as a reusable notepad with a status light.

  • str("") erases everything written on the notepad.
  • clear() turns off warning lights such as end reached or reading failed.

Erasing the notepad does not automatically turn off the warning light, and turning off the warning light does not erase the notepad. When reusing the stream, usually do both.

Take Quiz

Syntax and Examples

The primary operations are:

#include <sstream>
#include <string>

std::stringstream stream;

stream.str("Hello");       // Replace the stream's stored text.
std::string text = stream.str(); // Get a copy of the stored text.

stream.str(""); // Erase stored text.
stream.clear();   // Reset eof/fail/bad state flags.

Here is a complete example that reuses one stream:

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

int main() {
    std::stringstream stream;

    stream << "Order #" << 42;
    std::cout << stream.str() << '\n';

    // Reset before building different text.
    stream.str("");
    stream.clear();

    stream << "Order #" << 43;
    std::cout << stream.str() << '\n';
}

Output:

Order #42
Order #43

If you omit stream.str(""), the second write appends to the existing buffer and produces Order #42Order #43.

Step by Step Execution

Consider parsing one value and then reusing the stream for another:

#include <iostream>
#include <sstream>

int main() {
    std::stringstream input("25");

    int first = 0;
    input >> first;

    int unused = 0;
    input >> unused; // No more input: eofbit and/or failbit is set.

    input.str("90"); // Replace old text with new text.
    input.clear();    // Allow extraction again by resetting state flags.

    int second = 0;
    input >> second;

    std::cout << first << ", " << second << '\n';
}

Execution flow:

  1. input starts with the text "25".
  2. input >> first reads 25, so first becomes 25.
  3. The next extraction cannot read another integer because there is no more input. The stream enters a failed/end state.
  4. input.str("90") replaces "25" with "90", but it does not guarantee that previous failure flags are removed.
  5. input.clear() resets those flags.
  6. input >> second can now read 90.
  7. The output is 25, 90.

A reliable reuse order is:

input.str("");
input.clear();

Then write or assign the next content.

Real World Use Cases

std::stringstream reset patterns appear in many everyday C++ tasks:

  • Formatting log messages: Build a message, send it to a logger, then reset the stream for the next message.
  • Parsing CSV-like fields: Put each field into a stream, parse it, and reuse the same stream for the next field.
  • Converting strings to numbers: Parse user input such as "123" into an int, then reset before validating another input.
  • Building API payload fragments: Assemble JSON-like or query-string text in a loop.
  • Tests: Reuse an input stream to test several parsing cases without constructing a new object each time.

For simple one-time formatting, constructing a new local std::ostringstream is often clearer. Resetting is most useful when reuse is intentional, such as inside a loop.

Take Quiz

Real Codebase Usage

In real projects, developers usually choose one of two patterns.

Create a fresh local stream

This is the clearest option when the stream is used once per operation:

std::string formatUser(int id, const std::string& name) {
    std::ostringstream out;
    out << "id=" << id << ", name=" << name;
    return out.str();
}

The stream is destroyed when the function returns, so no reset is needed.

Reuse a stream in a loop

If profiling shows that repeated stream creation is undesirable, reset the stream explicitly:

std::stringstream parser;

for (const std::string& field : fields) {
    parser.str(field);
    parser.clear();

    int value = 0;
    if (parser >> value) {
        // Use value.
    } else {
        // Handle invalid field.
    }
}

Validate the entire input

Successful extraction does not always mean the entire string was valid. For example, "12abc" can initially extract 12. Check for trailing content:

std::stringstream parser("12abc");
int value = 0;
char extra = '\0';

if ((parser >> value) && !(parser >> extra)) {
    // The input contains exactly one integer.
} else {
    // Invalid or trailing characters found.
}

When parsing in production code, always check the stream state rather than assuming extraction succeeded.

Common Mistakes

Calling clear() to erase text

This does not erase the internal buffer:

std::stringstream stream;
stream << "old text";
stream.clear();

// stream.str() is still "old text"

Use stream.str("") to erase the text.

Calling empty() directly on a stringstream

This is invalid because std::stringstream has no empty() member:

std::stringstream stream;
// stream.empty(); // Error: no such member function

Check a copy of the underlying string instead:

if (stream.str().empty()) {
    // No buffered characters.
}

Clearing text but leaving failure flags set

After a failed extraction, replacing the text alone may not make a later read work:

std::stringstream stream("not-a-number");
int number = 0;
stream >> number; // Fails.

stream.str("42");
// stream >> number; // May still fail because failbit remains set.

Fix it by resetting both aspects:

stream.str("42");
stream.clear();
stream >> number;

Forgetting that output appends

Writing with << adds characters at the current output position. If you reuse an output stream without resetting its text, old content remains:

std::ostringstream out;
out << "first";
out << "second";

// out.str() is "firstsecond"

Call out.str("") before building an unrelated message.

Assuming str() returns a reference

stream.str() returns a std::string value. Editing that returned value does not edit the stream:

std::stringstream stream("hello");
std::string copy = stream.str();
copy = "changed";

// stream still contains "hello"

Use the setter form to replace stream content:

stream.str("changed");

Comparisons

OperationWhat it changesDoes it remove buffered text?Typical use
stream.str("")The internal string bufferYesStart a new message or input value
stream.clear()Error/state flagsNoRecover after EOF or a failed read
stream.str()Returns a copy of buffered textNoGet the generated or stored text
stream.seekg(0)Read positionNoRead existing content again from the start
stream.seekp(0)Write positionNoChange where output is written

seekg() and seekp() are not replacements for clearing. They move positions within existing content; they do not remove that content.

Stream typeSupports reading (>>)Supports writing (<<)Best for
std::istringstreamYesNoParsing a string
std::ostringstreamNoYesBuilding a string
std::stringstreamYesYesReading and writing the same string buffer
Take Quiz

Cheat Sheet

#include <sstream>

std::stringstream stream;
TaskCode
Get buffered textstd::string text = stream.str();
Replace buffered textstream.str("new text");
Erase buffered textstream.str("");
Reset eofbit / failbitstream.clear();
Fully reset for reusestream.str(""); stream.clear();
Check whether stored text is emptystream.str().empty()
Check whether parsing succeededif (stream >> value) { /* ... */ }

Key rule: str("") clears characters; clear() clears state flags.

For a stream that has failed and must be reused:

stream.str("");
stream.clear();

FAQ

Does std::stringstream::clear() erase the string?

No. clear() resets stream state flags such as failbit and eofbit. Use str("") to erase stored characters.

How do I completely reset a std::stringstream?

Use both operations:

stream.str("");
stream.clear();

This removes text and clears error state.

Why does reading from my stringstream still fail after I assign new text?

A previous read may have set failbit or eofbit. After assigning text with str(...), call clear() before reading again.

Does std::stringstream have an empty() function?

No. Use stream.str().empty() to check whether its current buffered string contains no characters.

Should I use std::stringstream, std::istringstream, or std::ostringstream?

Use istringstream for reading text, ostringstream for creating text, and stringstream only when you need both reading and writing.

Do I need to clear a newly created stringstream?

No. A newly constructed stream has an empty buffer and a good state. Resetting is only needed when reusing an existing stream.

Can I reuse a stream after parsing invalid input?

Yes. Replace or erase its text with str(...), then call clear() to remove the failed state before the next parse.

Take Quiz

Mini Project

Description

Build a small command parser that reads integer values from several text commands. The project demonstrates how to reuse one std::stringstream safely after both successful and failed parsing attempts.

Goal

Parse commands such as "add 12" and report whether each command contains a valid integer value.

Requirements

Use one reusable std::stringstream for every command.

Reset the stream before parsing each new command.

Accept commands containing exactly an action and one integer.

Reject commands with a missing, invalid, or extra value.

Print a useful result for every command.

Take Quiz

Keep learning

Related questions

View more