The following program prints 0.
#include <ostream>
#include <string>
#include <sstream>
#include <iostream>
int main()
{
std::string subjectString("subject");
std::ostream tempStream(NULL);
tempStream << subjectString;
std::ostream& updatedStream = tempStream;
std::stringstream ss;
ss << updatedStream;
std::cout << ss.str() << std::endl;
return 0;
}
Why?
EDIT
As per Niall's sugesstion, I tried:
#include <ostream>
#include <string>
#include <sstream>
#include <iostream>
int main()
{
std::string subjectString("subject");
std::stringbuf buffer;
std::ostream tempStream(&buffer);
buffer.sputn(subjectString.c_str(), subjectString.size());
std::stringstream ss;
ss << tempStream;
std::cout << ss.str() << std::endl;
return 0;
}
Even this prints an address. Not the actual string.
The construction of std::ostream requires a buffer (not NULL).
In addition, basic_stream objects are not copyable;
basic_ostream( const basic_ostream& rhs ) = delete;
Reference;
http://en.cppreference.com/w/cpp/io/basic_ostream/basic_ostream
Try something more like this;
// ...
std::stringbuf buffer;
std::ostream tempStream(&buffer);
// ...
To associate a buffer with the stream.
Following on some of the discussions and edits;
In general, I would not directly manipulate the buffer, you should rather use the stream instead tempStream.write(...). The exact details are beyond the immediate question/problem; being the initialisation of the first stream with the buffer and streaming content into that stream. If all you want to do with the code is check if the data is in the buffer, then you could use tempStream.rdbuf()->sgetn(...).
You have already mentioned that this is part of a larger problem.
In the context of some the comments here and the original problem; this could be a case in which direct manipulation of the buffer is needed (in much the same way as the stream would). Your implementation would need to be well tested since this is not "the usual" way of working with streams, but it can work; .rdbuf() is the manner in which you can get to the underlying buffer. I don't have an exact snippet (maybe that's another question), but you can "clear the buffer" by resetting the position(s) of the put and get areas to be the same (see the positioning, put and get area functions of the buffer - std::ostream::seekp was mentioned as being used to deal with this). I think you standard library implementation of stringstream could also offer some useful hints.
Because tempStream has no stream to hold anything.
ss.str() returns NULL (0).
Related
I am using Cereal C++ v1.1.1 and similar to the example given in the documentation I am trying the following:
#include <sstream>
#include <iostream>
#include <cereal/archives/json.hpp>
int main() {
std::ostringstream os;
cereal::JSONOutputArchive archive(os);
int x = 12;
archive(CEREAL_NVP(x));
std::cout << os.str(); // JUST FOR DEMONSTRATION!
}
I expect to have the following:
{
"x":12
}
but the closing curly brace is missing. Any idea what is missing in the code?
Update:
adding archive.finishNode() seems to solve the problem. But I would say that it's not the solution. According to the operator() documentation, calling the operator serializes the input parameters, why should I add the finishNode extra?
I was having the same problem, and found the solution in a comment on an issue filed on Cereal's GitHub: https://github.com/USCiLab/cereal/issues/101
The documentation states "Archives are designed to be used in an RAII
manner and are guaranteed to flush their contents only on
destruction..." (http://uscilab.github.io/cereal/quickstart.html).
Your problem is that you are trying to print the contents of the
stringstream before the archive has been destroyed. At this point, the
archive has no idea whether you will want to write more data to it in
the future, so it refrains from streaming out the closing brace. You
need to make sure the archive's destructor has been called before
printing out the stringstream.
Try this:
int main()
{
std::stringstream ss;
{
cereal::JSONOutputArchive archive( ss );
SomeData myData;
archive( myData );
}
std::cout << ss.str() << std::endl;
return 0;
}
Please see the documentation for more information.
I was going through these two class implementations and found out that the strstream class is deprecated.
And if I use the stringstream class as replacement, then there is big difference between how they log in the buffer since the stringstream class object maintains a deep copy of the buffer.
Has anyone faced any problem while replacing strstream with stringstream class?
What would be the output of this code and why?
#include<iostream>
#include <sstream>
#include <strstream>
int main(){
char strArr[] = "Soheb Khan is great";
char stringArr[] = "TurboCharging";
std::strstream strStream(strArr,19);
std::stringstream stringStream(std::string(stringArr,19));
std::cout<<"Before Modification strArr= "<<strArr<<" & stringArr= "<<stringArr<<std::endl;
strStream << "Fifa 2012 is nice";
stringStream << "Sometimes its sucks";
std::cout<<"After Modification strArr= "<<strArr<<" & stringArr= "<<stringArr<<std::endl;
return 0;
}
The classes from <strstream> are hideous to use. When they were more popular I haven't seen any correct production used (well, they got corrected when I spotted the problems). Either people didn't terminate the string using std::ends or they didn't release the memory using s.freeze(0) (or, most often, both). Although the <sstream> class do create a copy I haven't found this to be a problem.
In case memory allocation actually matters for your use case, either because you need to allocate large chunks or because you have many of them, you can take control easily and have data read from or written to buffers you provide using a custom stream buffer. For example, a stream buffer writing to a readily allocate chunk of memory is trivial to write:
struct omembuf
: std::streambuf {
{
omembuf(char* base, std::size_t size) {
this->setp(base, base + size);
}
char* begin() const { return this->pbase(); }
char* end() const { return this->pptr(); }
};
For a project, I'd like to use stringstream to carry on data. To achieve this goal, I have to pass some stringstream as parameter to some function, but when I output the stringstreams, I see something like an address.
The code :
#include <iostream>
#include <sstream>
void doStuff(const std::iostream& msg)
{
std::cerr << msg << std::endl;
}
int main(void)
{
doStuff(std::stringstream("av"));
}
The output is :
0xbff4eb40
Can someone explains why I get an address when passing an rvalue ?
And why can't I pass a stringstream by value ?
You probably want to access the string on which the stringstream is storing its data:
void doStuff(const std::stringstream& msg)
{
std::cerr << msg.str() << std::endl;
}
What is happening in your code is that iostreams contain a void* operator which returns 0 if the stream contains any error or has reached EOF, and another value otherwise. This is usefull for error checking.
When you try to write you stream to std::cerr, the compiler realizes that the stream can be converted to a void* using that operator, and that a void* can be written to a ostream(the operator<< has been defined), and therefore uses it.
Note that i changed the method's signature so that it receives an std::stringstream as an argument, since std::iostream::str is not defined(this method is only available on string streams).
You get an address because it (like other streams) has a conversion to void * (which is primarily useful as a Boolean, to see whether reading/writing the stream has failed).
You can't pass it by value, because streams (again, in general, not just stringstreams) don't support copying and/or assigning.
To print the content of the stream, you could do something like:
void dostuff(std::iostream &msg) {
std::cerr << msg.rdbuf() << "\n";
}
Edit: Here's a complete demo program:
#include <iostream>
#include <sstream>
void show(std::ostream &os) {
std::cout << os.rdbuf() << "\n";
}
int main(){
std::stringstream test("whatever");
show(test);
return 0;
}
When I execute it, the output I get is the expected "whatever".
I have a C++ code that has a lot of functions which receives ostream as argument. I wanted to unit test those functions, for that I have to verify ostream object data after execution to the function. I can redirect output stream to a file but I wanted to check if I can create a temporary buffer and redirect the output stream to the buffer and read from that buffer.
You can use std::stringstream as an in memory std::ostream:
#include <iosfwd>
#include <sstream>
#include <cassert>
void my_func(std::ostream& out) {
out << "test";
}
int main() {
std::ostringstream buf;
my_func(buf);
assert(buf.str() == "test");
}
I have an Image class which has the following implementation
friend std::ostream& operator << ( std::ostream &os,Image* &img);
So I can serialize it by calling
ostm << img; // which will write an string into the ostream.
Is it possible to get that string out of the ostream or serialize it directly into an string object?
Thanks!
The solutions worked like a charm. Thank you so much!
Yes, you can use a std::ostringstream.
E.g.
#include <sstream>
#include <string>
#include <stdexcept>
std::string Serialize( const Image& img )
{
std::ostringstream oss;
if (!(oss << img))
{
throw std::runtime_error("Failed to serialize image");
}
return oss.str();
}
Presumably your actual object is an iostream, or a stringstream. If an iostream, you can do this:
std::iostream ss;
ss << "Some text\nlol";
std::string all_of_it((std::istreambuf_iterator<char>(ss)), std::istreambuf_iterator<char>());
std::cout << all_of_it; // Outputs: "Some text", then "lol" on a new line;
You need the istreambuf_iterator, hence the requirement for a bidirectional stream like iostream. Whenever you have extraction as well as insertion, you should use this, or a stringstream (or an fstream if working with files).
For a stringstream, just use its .str() member function to obtain its buffer as a string.