Step 3 of 6
Building strings with ostringstream
std::ostringstream is the output twin of istringstream. You write to it with <<, exactly as you would to std::cout, and then take the finished text with .str(). It's the easy way to build a string from numbers and pieces, with all the formatting tools from the last step.
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
std::string money(long cents) {
std::ostringstream out;
out << "quot; << cents / 100 << "." << std::setw(2) << std::setfill('0') << cents % 100;
return out.str();
}
std::string bullet_list(const std::vector<std::string>& items) {
std::ostringstream out;
for (const auto& s : items) out << "- " << s << "\n";
return out.str();
}
int main() {
std::cout << money(1999) << " " << money(5) << " " << money(120) << "\n";
std::cout << bullet_list({"eggs", "milk"});
}
$19.99 $0.05 $1.20
- eggs
- milk
How it works
- Each call makes its own
ostringstream, so formatting settings likesetfill('0')don't leak intostd::cout. .str()returns a copy of everything written so far.- Anything that can be printed with
<<can be written into it, including your own types once you've writtenoperator<<for them.
Separators: the fencepost problem
Joining values with a separator is a classic off-by-one trap. With 3 values there are only 2 separators, so a naive loop that writes value, sep each time leaves a trailing separator. Two common fixes:
for (size_t i = 0; i < v.size(); i++) {
if (i > 0) out << sep; // separator before every item except the first
out << v[i];
}
or write the first item before the loop and sep, item inside it (after checking the vector isn't empty). Test with an empty vector and a single element: they should give "" and "7".
(C++20 also has std::format, covered later. Streams are still everywhere in existing code.)
Your turn: write std::string join(const std::vector<int>& v, const std::string& sep) that returns the numbers separated by sep, like "1, 2, 3".
Previous: Formatting tables with iomanip Next: Reading files with ifstream