std::stringstream
The std::stringstream class provided by C++'s <sstream> header lets you treat a string as a stream. Because it uses the same interface as std::cin / std::cout, it is widely used for converting between numbers and strings and for token splitting.
Syntax
// ========================================
// Basic syntax of std::stringstream
// ========================================
#include <sstream>
#include <string>
// --- Number → String ---
int num = 42;
std::stringstream ss;
ss << num; // Write to the stream
std::string str = ss.str(); // Retrieve as a string
// --- String → Number ---
std::string input = "123";
std::stringstream ss2(input); // Initialize with a string
int val;
ss2 >> val; // Read from the stream
// --- Reuse requires clearing the stream state ---
ss.str(""); // Clear the buffer
ss.clear(); // Reset error flags
ss << 99;
Member Functions and Operations
| Operation / Member | Description |
|---|---|
| ss << value | Writes a value to the stream. Any type supported by operator<< can be used, including numbers and strings. |
| ss >> variable | Reads a whitespace-delimited value from the stream. |
| ss.str() | Returns the stream's buffer content as a std::string. |
| ss.str(s) | Replaces the stream's buffer with string s. |
| ss.clear() | Resets the EOF, fail, and bad flags. Use together with str(""). |
| std::istringstream | A read-only stream. Used for parsing strings (token splitting, type conversion). |
| std::ostringstream | A write-only stream. Used for converting numbers to strings and building formatted output. |
Sample Code
dragonball_sstream.cpp
// ========================================
// dragonball_sstream.cpp
// Uses Dragon Ball character data to demonstrate
// string-to-number and number-to-string conversion,
// token splitting, and formatted output with std::stringstream
// ========================================
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
// ========================================
// Helper: convert an integer to a string
// Uses std::ostringstream
// ========================================
std::string intToStr(int n) {
std::ostringstream oss;
oss << n;
return oss.str();
}
// ========================================
// Helper: convert a string to an integer
// Uses std::istringstream; returns 0 on failure
// ========================================
int strToInt(const std::string& s) {
std::istringstream iss(s);
int n = 0;
iss >> n;
return n;
}
// ========================================
// Split a comma-separated string into tokens
// Uses std::istringstream + std::getline
// ========================================
std::vector<std::string> splitCSV(const std::string& line) {
std::vector<std::string> tokens;
std::istringstream iss(line);
std::string token;
while (std::getline(iss, token, ',')) {
tokens.push_back(token);
}
return tokens;
}
// ========================================
// Return a formatted character info string
// Built with std::ostringstream
// ========================================
std::string formatCharacter(const std::string& name, int power, const std::string& race) {
std::ostringstream oss;
oss << "Name: " << name
<< " Power: " << power
<< " Race: " << race;
return oss.str();
}
int main() {
// ============================================
// 1. Number → String conversion
// ============================================
std::cout << "=== Number → String ===" << std::endl;
int gokuPower = 9000000; // Son Goku's power level (Super Saiyan 3)
std::string gokuPowerStr = intToStr(gokuPower);
std::cout << "Goku's power (string): " << gokuPowerStr << std::endl;
// Build multiple values at once with std::ostringstream
std::ostringstream oss;
oss << "Vegeta" << " power=" << 8500000 << " race=Saiyan";
std::cout << oss.str() << std::endl;
std::cout << std::endl;
// ============================================
// 2. String → Number conversion
// ============================================
std::cout << "=== String → Number ===" << std::endl;
std::string piccoloPowerStr = "3200000"; // Piccolo's power level
int piccoloPower = strToInt(piccoloPowerStr);
std::cout << "Piccolo's power (int): " << piccoloPower << std::endl;
// Read multiple values separated by spaces
std::string gohanData = "7500000 Half-Saiyan"; // Gohan's data
std::istringstream issGohan(gohanData);
int gohanPower;
std::string gohanRace;
issGohan >> gohanPower >> gohanRace; // Read in order, separated by spaces
std::cout << "Gohan's power: " << gohanPower << " Race: " << gohanRace << std::endl;
std::cout << std::endl;
// ============================================
// 3. CSV token splitting
// ============================================
std::cout << "=== CSV Token Split ===" << std::endl;
std::string csvLine = "Frieza,120000000,Frieza-Race,Final-Form";
std::vector<std::string> fields = splitCSV(csvLine);
std::cout << "CSV: " << csvLine << std::endl;
for (int i = 0; i < (int)fields.size(); i++) {
std::cout << " Field[" << i << "]: " << fields[i] << std::endl;
}
std::cout << std::endl;
// ============================================
// 4. Reusing std::stringstream (str + clear)
// ============================================
std::cout << "=== stringstream Reuse ===" << std::endl;
std::stringstream ss;
// First use: write Goku's data
ss << "Goku " << 9000000;
std::cout << "Round 1: " << ss.str() << std::endl;
// To reuse, clear the buffer with str("") and reset flags with clear()
ss.str("");
ss.clear();
// Second use: write Vegeta's data
ss << "Vegeta " << 8500000;
std::cout << "Round 2: " << ss.str() << std::endl;
std::cout << std::endl;
// ============================================
// 5. Formatted output summary
// ============================================
std::cout << "=== Character List ===" << std::endl;
std::cout << formatCharacter("Son Goku", 9000000, "Saiyan") << std::endl;
std::cout << formatCharacter("Vegeta", 8500000, "Saiyan") << std::endl;
std::cout << formatCharacter("Piccolo", 3200000, "Namekian") << std::endl;
std::cout << formatCharacter("Son Gohan", 7500000, "Half-Saiyan") << std::endl;
std::cout << formatCharacter("Frieza", 120000000, "Frieza-Race") << std::endl;
return 0;
}
# Compile g++ -std=c++11 dragonball_sstream.cpp -o dragonball_sstream # Run ./dragonball_sstream === Number → String === Goku's power (string): 9000000 Vegeta power=8500000 race=Saiyan === String → Number === Piccolo's power (int): 3200000 Gohan's power: 7500000 Race: Half-Saiyan === CSV Token Split === CSV: Frieza,120000000,Frieza-Race,Final-Form Field[0]: Frieza Field[1]: 120000000 Field[2]: Frieza-Race Field[3]: Final-Form === stringstream Reuse === Round 1: Goku 9000000 Round 2: Vegeta 8500000 === Character List === Name: Son Goku Power: 9000000 Race: Saiyan Name: Vegeta Power: 8500000 Race: Saiyan Name: Piccolo Power: 3200000 Race: Namekian Name: Son Gohan Power: 7500000 Race: Half-Saiyan Name: Frieza Power: 120000000 Race: Frieza-Race
Additional Pattern: Token Splitting with istringstream
dragonball_sstream2.cpp
// ========================================
// dragonball_sstream2.cpp
// Demonstrates space-delimited token splitting with istringstream
// and zero-padded formatting with ostringstream
// ========================================
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <iomanip>
// Split a space-delimited string into tokens
std::vector<std::string> splitBySpace(const std::string& line) {
std::vector<std::string> tokens;
std::istringstream iss(line);
std::string token;
while (iss >> token) {
tokens.push_back(token);
}
return tokens;
}
int main() {
// --- Space-delimited token splitting ---
std::string roster = "Goku Vegeta Piccolo Krillin Frieza";
std::vector<std::string> names = splitBySpace(roster);
std::cout << "=== Roster ===" << std::endl;
for (int i = 0; i < (int)names.size(); i++) {
std::cout << " " << (i + 1) << ". " << names[i] << std::endl;
}
// --- Zero-padded formatting with ostringstream ---
std::cout << std::endl << "=== Power Ranking ===" << std::endl;
int powers[] = {9000000, 8500000, 3200000, 2800000, 120000000};
for (int i = 0; i < 5; i++) {
std::ostringstream oss;
oss << std::setw(3) << std::setfill('0') << (i + 1)
<< ". " << std::setw(12) << std::setfill(' ') << powers[i];
std::cout << oss.str() << std::endl;
}
return 0;
}
# Compile g++ -std=c++11 dragonball_sstream2.cpp -o dragonball_sstream2 # Run ./dragonball_sstream2 === Roster === 1. Goku 2. Vegeta 3. Piccolo 4. Krillin 5. Frieza === Power Ranking === 001. 9000000 002. 8500000 003. 3200000 004. 2800000 005. 120000000
Common Mistake: Forgetting to reset stream state
When reusing a std::stringstream, clearing the buffer with str("") alone is not enough. The EOF and error flags remain set, causing the next read operation to fail. Always call both str("") and clear() together.
NG: str("") alone leaves flags set
std::stringstream ss("9000000");
int power;
ss >> power; // EOF flag is set after reading
ss.str("8500000"); // Replace buffer contents, but...
ss >> power; // EOF flag still set — read fails (power unchanged)
std::cout << power << std::endl; // → still 9000000
OK: call str("") and clear() together
std::stringstream ss("9000000");
int power;
ss >> power;
ss.str("8500000");
ss.clear(); // Reset flags
ss >> power; // Read succeeds
std::cout << power << std::endl; // → 8500000
Common Mistake: Misunderstanding str() vs clear()
str() operates on the buffer content (the string data). clear() resets the stream's state flags (eofbit, failbit, badbit), not the buffer content. Their roles are independent, and calling just one is often insufficient. If you only write to the stream and reset the buffer, str("") alone is enough. But if you have read from the stream and want to reuse it, you need both.
Write-only: str("") alone is sufficient
std::ostringstream oss;
oss << "Goku " << 9000000;
std::cout << oss.str() << std::endl;
oss.str(""); // Clear buffer (no need for clear())
oss << "Vegeta " << 8500000;
std::cout << oss.str() << std::endl;
After reading, clear() is also required
std::istringstream iss("3200000");
int n;
iss >> n; // EOF flag is set
// iss.str("2800000") alone — next >> will fail
iss.str("2800000");
iss.clear(); // Reset flags
iss >> n; // reads 2800000
std::cout << n << std::endl; // → 2800000
Overview
std::stringstream (<sstream>) is a class that lets you read from and write to an in-memory string as if it were a stream. Writing with operator<< and retrieving with str() converts numbers to strings; reading with operator>> converts strings to numbers. Since C++11, dedicated functions like std::to_string() and std::stoi() are available for simple conversions, but std::stringstream remains more flexible when you need to format multiple values together or split a string by a delimiter. When reusing the same object, remember that ss.str("") clears the buffer while ss.clear() resets the EOF flag — both are needed. For read-only use, prefer std::istringstream; for write-only use, prefer std::ostringstream to make your intent explicit.
If you find any errors or copyright issues, please contact us.