How do you prepend to std::stringstream? - c++

std::stringstream ss;
int number = 0x12345678;
ss << std::hex << number;
cout << ss.str();
This will produce 12345678
I want to make it as 0x12345678. How can I prepend 0x in front of ss.str()?

The probably simplest way to do this is to change the formatting of the stringstream ss: Make it automatically prepend the number base with std::showbase:
#include <sstream>
#include <iostream>
int main()
{
std::stringstream ss;
int number = 0x12345678;
ss << std::showbase << std::hex << number; // prepends the 0x automagically
std::cout << ss.rdbuf(); // empties ss
}
Note that I changed the output from cout << ss.str() to cout << ss.rdbuf(). This modifies the stream ss (it is empty afterwards), but requires no copy as in the OP's example.
Once you've put the number into the stringstream, there's no simple way I know of to prepend the 0x in this stringstream. You could then however print it before printing the contents of the stream to cout:
std::cout << "0x" << ss.rdbuf();

Related

How can I obtain the length of a const stringstream's buffer without copying or seeking?

I have a const std::stringstream and a desire to find out how many bytes there are in its underlying string buffer.
I cannot seekg to the end, tellg then seekg to the start again, because none of these operations are available constly.
I do not want to get the str().size() because str() returns a copy and this may not be a trivial amount of data.
Do I have any good options?
(The stream itself is presented to me as const, only because it is a member of another type, and I receive a const reference to an object of that type. The stream represents the contents of a "document", its encapsulating object represents a CGI response and I am trying to generate an accurate Content-Length HTTP header line from within operator<<(std::ostream&, const cgi_response&).)
I've never been very comfortable with stream buffers, but this seems to work for me:
#include <iostream>
#include <sstream>
std::stringstream::pos_type size_of_stream(const std::stringstream& ss)
{
std::streambuf* buf = ss.rdbuf();
// Get the current position so we can restore it later
std::stringstream::pos_type original = buf->pubseekoff(0, ss.cur, ss.out);
// Seek to end and get the position
std::stringstream::pos_type end = buf->pubseekoff(0, ss.end, ss.out);
// Restore the position
buf->pubseekpos(original, ss.out);
return end;
}
int main()
{
std::stringstream ss;
ss << "Hello";
ss << ' ';
ss << "World";
ss << 42;
std::cout << size_of_stream(ss) << std::endl;
// Make sure the output string is still the same
ss << "\nnew line";
std::cout << ss.str() << std::endl;
std::string str;
ss >> str;
std::cout << str << std::endl;
}
The key is that rdbuf() is const but returns a non-const buffer, which can then be used to seek.
If you want to know the remaining available input size:
#include <iostream>
#include <sstream>
std::size_t input_available(const std::stringstream& s)
{
std::streambuf* buf = s.rdbuf();
std::streampos pos = buf->pubseekoff(0, std::ios_base::cur, std::ios_base::in);
std::streampos end = buf->pubseekoff(0, std::ios_base::end, std::ios_base::in);
buf->pubseekpos(pos, std::ios_base::in);
return end - pos;
}
int main()
{
std::stringstream stream;
// Output
std::cout << input_available(stream) << std::endl; // 0
stream << "123 ";
std::cout << input_available(stream) << std::endl; // 4
stream << "567";
std::cout << input_available(stream) << std::endl; // 7
// Input
std::string s;
stream >> s;
std::cout << input_available(stream) << std::endl; // 4
stream >> s;
std::cout << input_available(stream) << std::endl; // 0
}
This is similar to #Cornstalks solution, but positions the input sequence correctly.
This should work :))
#include <iostream>
#include <sstream>
#include <boost/move/move.hpp>
int main()
{
const std::stringstream ss("hello");
std::cout << boost::move(ss).str().size();
}

Printing out a stringstream using str() and rdbuf()

When I have:
std::ostringstream oss("Hello");
Why does this work:
std::cout << oss.str();
but this doesn't print anything:
std::cout << oss.rdbuf();
Reading the definition of operator<<(std::ostream&, std::streambuf*) say that it will print characters from the buffer. Does oss.rdbuf() not contain anything?
This issue is related to the fact that here, oss is ostringstream object (ostringstream is output stream so its destination is to write to it and not to read from it) and to fact how streams manage its internal buffer.
You can change
std::ostringstream oss("Hello");
to
std::istringstream oss("Hello"); // or std::stringstream oss("Hello");
and it will work as expected. Alternatively use
std::cout << oss.rdbuf()->str(); // this will print a copy of all buffer content
Example:
#include <iostream>
#include <sstream>
int main() {
std::ostringstream oss("Hello");
std::istringstream oss2("Hello");
cout << oss.rdbuf()->str() << endl; // prints "Hello"
cout << oss2.rdbuf(); // prints "Hello"
return 0;
}
Objects of ostringstream class use a string buffer that contains a sequence of characters. This sequence of characters can be accessed directly as a string object, using member str. That explains first part.
std::ostringstream oss("Hello");
std::cout << oss.str(); // works
The rdbuf returns pointer to the associated streambuf object, which is charge of all input/output operations. Thus, you need to use str() again to print the contents as in:
std::cout << oss.rdbuf()->str();
instead of:
std::cout << oss.rdbuf();

ostringstream breaks cout?

I want to output the content of a ostringstream to some other stream (for example std::cout). I know that I can use std::ostringstream::str() but I assume it has an overhead on copying the stream contents to a string and then further to the other stream. I found that I could use std::ostringstream::rdbuf() (Comment suggesting that has 25 votes). But it breaks std::cout as is shown in the output of the test program below. Am I doing something wrong?
#include <iostream>
#include <sstream>
int main(int argc, char const *argv[])
{
std::ostringstream ss;
ss << "some data" << std::endl;
std::cerr << std::cout << std::endl;
std::cout << "start" << std::endl;
std::cout << ss.str();
std::cout << ss.rdbuf();
std::cout << "end" << std::endl;
std::cerr << std::cout << std::endl;
return 0;
}
Results in:
0x6013b8
start
some data
0
Your problem is that the rdbuf() buffer for an ostringstream is, as you might expect from the name, write only (the ostringstream returns the string through the str() method). You can't read the data back out of it through the buffer pointer.
Change your ostringstream to stringstream and it should work fine.

using stringstream to print a rounded floating point number

i have floating point variables "lmin" and "lmax". i wish to display only 4 significant digits. i am currently using something i have found online of the form ...
string textout;
stringstream ss;
ss << lmin;
textout = ss.str();
output(-0.5, -0.875, textout);
ss.str("");
ss << lmax;
textout = ss.str();
output(0.2, -0.875, textout);
where "output" is simply a function i wrote to parse the string and print it to the screen. the important point, is how do i print only a ROUNDED version of lmin and lmax to ss?
Use std::setprecision to specify the number of digits after the decimal point.
#include <sstream>
#include <iostream>
#include <iomanip>
int main()
{
double d = 12.3456789;
std::stringstream ss;
ss << std::fixed << std::setprecision( 4 ) << d;
std::cout << ss.str() << std::endl;
}
Output:
12.3457
Simply use ss.precision( 4 ) or ss << std::setprecision( 4 ) before inserting the output.

how copy from one stringstream object to another in C++?

I have std::stringstream object ss1. Now, I would like to create another copy from this one.
I try this:
std::stringstream ss2 = ss1;
or:
std::stringstream ss2(ss1)
neither works
The error message is like this:
std::ios::basic_ios(const std::ios &) is not accessible from
bsl::basic_stringstream,
bsl::allocator>::basic_stringstream(const
bsl::basic_stringstream,
bsl::allocator>&).
Indeed, streams are non-copyable (though they are movable).
Depending on your usage, the following works quite well:
#include <iostream>
#include <sstream>
int main()
{
std::stringstream ss1;
ss1 << "some " << 123 << " stuff" << std::flush;
std::stringstream ss2;
ss2 << ss1.rdbuf(); // copy everything inside ss1's buffer to ss2's buffer
std::cout << ss1.str() << std::endl;
std::cout << ss2.str() << std::endl;
}
Output:
some 123 stuff
some 123 stuff
As std::stringstream does not provide a copy constructor, you have to build it from the std::string ss1outputs:
std::stringstream ss2(ss1.str());