I've a program that used to run as a commandline, hence has lots of couts in it. I was wondering if there was a way of creating an ostream object in the class that calls this program and initialize that programs constructor with something like
Import(ostream & text_out= std::cout):out(text_out)
and replace all my calls to cout with out, thereby switching where the output goes.
At the end of each function call, I could then extract the ostream object to a string, and send it to my MFC object.
This would mean my base code would be good if called either as a commandline or an MFC program, if I could get it to work. This could be me thinking along the wrong track, but I'm curious to see if this is possible.
You can use ostringstream:
std::ostringstream oss;
std::ostream &os = oss;
os << "Hello" << endl;
std::string str = oss.str(); // str == "Hello\n"
It seems you are looking for std::ostringstream.
Related
I just started learning C++, and I saw some function in C++ primer like that:
double total_receipt(ostream &os)const{...}
then I try to find the address of cout by using this code: "cout << &cout << endl;"
and that's no difference between ostream &os and direct use cout.
So why not just use cout instead of ostream &os? Or maybe it's just a "good" habit?
First notice:
cout is an object (check these docs)
ostream is a class (check these docs)
When you declare a method, you need to use the class names for the parameters, so if your class uses an "output stream" (that's what ostream means) then you declare your function like:
double total_receipt(ostream &os)
You can't create the function like this:
double total_receipt(cout) // doesn't work
Now, if your question is about what is the difference between declaring the total_receipt function like this:
double total_receipt(ostream &os) {
os << "hello world" << std::endl;
}
or like this:
double total_receipt() {
std::cout << "hello world" << std::endl;
}
That's up to you. Usually, we use the first one as that allows to invoke the function with other things besides cout, like:
ofstream out_file("my_file.txt");
total_receipt(out_file);
So, you can pass to that function any object of classes derived from ostream, like ofstream in the example. This means, your function can print to a file, besides printing to the terminal, so you add more functionality if you need it.
I have a main function that prints a sudoku game to the console as I play. I call a print board method which outputs the board along with a 2D array with the numbers. I've been modifying the game to output to the file after every cout:
cout << "puzzle created" << endl;
output << "puzzle created" << endl;
Then the problem is that there is an error when I try the same with a method:
sudoku.printBoard(); //method to print board to console
I can't simply say:
output << sudoku.printBoard();
and I can't say:
output << "number";
in the method in the board.cpp file either.
Does anyone know any way around this?
This is the problem with print() member functions, and the reason you shouldn't write them. At least, not like this. You've locked yourself into printing to stdout, and now that you want to print somewhere else instead, you're stuck.
Instead, have a function that prints where you tell it to. This may be stdout or a file or whatever.
The function will be declared like this:
void printBoard(std::ostream& os);
and inside its definition, you will use os rather than std::cout.
Then your code will look like this:
sudoku.printBoard(std::cout);
sudoku.printBoard(output);
It works because both std::cout and output are of types that derive from std::ostream.
If you need the cout variant a lot, and you don't want to provide the argument every time because it's getting messy, simply provide an overload:
void printBoard()
{
printBoard(std::cout);
}
Now you can still write:
sudoku.printBoard();
Whether this is more or less confusing for developers on your project is for you to decide.
If you don't have other things to print, so that this is the only function of its kind within the type of sudoku, a more idiomatic approach would be to create an operator<< for that type:
std::ostream& operator<<(std::ostream& os, const SudokuBoard& board)
{
board.printBoard(os);
return os;
}
Now you can use it like this:
std::cout << sudoku;
output << sudoku;
Make a class that takes two ostreams in the constructor. One of these can be std::cout. Store these in the class as references.
Create output stream operators (<<) and use those to write to the two streams.
To use this in other classes pass it as a reference in their constructor (look up dependency injection).
Pass ofstream as a reference to your funtion or simply return string from your function and print it in main() or callee function.
In 2nd case you go like this
string f()
{
ostringstream os;
os<<"whatever I want to print in output";
....
...
return os.str();
}
int main() or //womain() from wherever you call
{
output<<f()<<endl;
}
I try the following code:
ostringstream oss;
streambuf *psbuf, *backup;
backup = oss.rdbuf();
psbuf = cout.rdbuf();
oss.rdbuf(psbuf);
oss << things << endl;
oss.rdbuf(backup);
But unfortunately I get this error:
error: too many arguments to function call, expected 0, have 1
oss.rdbuf(backup);
But rdbuf has two overloads:
get (1) basic_streambuf<char_type,traits_type>* rdbuf() const;
set (2) basic_streambuf<char_type,traits_type>* rdbuf (basic_streambuf<char_type,traits_type>* sb);
Yes I know it says basic_streambuf but it really is just a typedef typedef basic_streambuf<char> streambuf;, so it should work. Why is it not working?
Even though std::ostringstream inherits rdbuf from std::basic_ios that overload will not be accessible due to the fact that std::basic_ostream also defines its own member-function named rdbuf, effectively hiding the overload(s) you are looking for.
You can get access to the member-function by casting your std::ostringstream instance to a std::ostream reference as in the below example:
std::ostringstream oss;
std::ostream& oss_ref = oss;
auto prev = oss_ref.rdbuf (std::cout.rdbuf ());
oss << "hello world"; // will print to the buffer of std::cout
oss_ref.rdbuf (prev); // reset
static_cast<std::ostream&> (oss).rdbuf (...) // equivalent
Why does std::basic_ostringstream define its own rdbuf?
Normally rdbuf returns a std::basic_streambuf* but std::ostringstream uses a std::basic_stringbuf.
Since one cannot overload based on return-type a decision was made to effectively hide the former overload in favour of the new one.
By returning a std::basic_stringbuf it's easy to see that std::ostringstream uses a stringbuf internally, and it also provides easier access to the str functions of std::basic_stringbuf (functions which doesn't exist in std::basic_streambuf).
Because in the class ostringstream (typedef of basic_ostringstream<char>), only the gettor version of rdbuf() was defined as its member function, so the settor version inheriting from base class was hided. You can use the settor version of rdbuf() by upcasting oss to the base class such as ostream.
I am working on a C++ code and I wish to do the following:
In the code there is a new type, T, there is a method defined on T that prints some information to a type FILE* variable.
I would like to do some work on this string inside of the program, so I would like to have a variable of type string (or even char*) that will contain what is printed to the screen (if I give the printing function stdout as the File*).
How can I do this ? maybe I can create some FILE* variable and then create (somehow) a string/char* variable with the information that is stored in that File* variable we created ?
Any help is appreciated!
POSIX 1.2008 fmemopen, open_memstream functions create a FILE* pointer which writes to (and/or reads from) memory.
If it does not work for your platform (and there is no other way to hook into FILE *), then you're out of luck.
The next thing I'd try is creating an anonymous pipe, (POSIX pipe, Windows CreatePipe), wrapping its writing side into FILE * (POSIX fdopen, plus Windows _open_osfhandle to get a CRT fd from HANDLE). Here you have to ensure that the pipe's buffer size is enough, or to spawn a thread for reading the pipe. Don't forget to fflush the writing side after the method is done (or use setbuf to disable buffering).
There are several platform-independent ways to do it.
In C++ you can use stringstream(http://www.cplusplus.com/reference/sstream/stringstream/), which has many << operator overloads. So if you pass a reference to ostream& (not oFstream) to the output method, you can easily switch between files, stadard output stream and string outputs, because all this streams are inherited from ostream. Then you can get std::string object from stringstream and get C-string from it if you need.
Code example:
Output function (or method, then you don't need the second argument from the example):
void PrintMyObjectToSomeStream(std::ostream& stream, const MyClass& obj)
{
stream << obj.pubField1;
stream << obj.pubField2;
stream << obj.GetPrivField1();
stream << "string literal";
stream << obj.GetPrivField2();
}
Usage:
MyClass obj1;
std::ofsstream ofs;
std::stringstream sstr;
//...open file for ofs, check if it is opened and so on...
//...use obj1, fill it's member fields with actual information...
PrintMyObjectToSomeStream(obj1,std::cout);//print to console
PrintMyObjectToSomeStream(obj1,sstr);//print to stringstream
PrintMyObjectToSomeStream(obj1,ofs);//print to file
std::string str1=sstr.str();//get std::string from stringstream
char* sptr1=sstr.str().c_str();//get pointer to C-string from stringstream
Or you can overload operator<<:
std::ostream& operator<<(std::ostream& stream, const MyClass& obj)
{
stream << obj1.pubField;
//...and so on
return stream;
}
then you can use it in this way:
MyClass obj2;
int foo=100500;
std::stringstream sstr2;
std::ofstream ofs;//don't forget to open it
//print to stringstream
sstr2 << obj2 << foo << "string lineral followed by int\n";
//here you can get std::string or char* as like as in previous example
//print to file in the same way
ofs << obj2 << foo << "string lineral followed by int\n";
Using FILE is more C than C++ but you can think how to switch between fpirntf and sprintf or use Anton's answer.
I would like to be able to do:
foo(stringstream()<<"number = " << 500);
EDIT: single line solution is crucial since this is for logging purposes. These will be all around the code.
inside foo will print the string to screen or something of the sort.
now since stringstream's operator<< returns ostream&, foo's signature must be:
foo(ostream& o);
but how can I convert ostream& to string? (or char*).
Different approaches to achieving this use case are welcome as well.
The obvious solution is to use dynamic_cast in foo. But the given
code still won't work. (Your example will compile, but it won't do what
you think it should.) The expression std::ostringstream() is a
temporary, you can't initialize a non-const reference with a temporary,
and the first argument of std::operator<<( std::ostream&, char const*)
is a non-const reference. (You can call a member function on a
temporary. Like std::ostream::operator<<( void const* ). So the code
will compile, but it won't do what you expect.
You can work around this problem, using something like:
foo( std::ostringstream().flush() << "number = " << 500 );
std::ostream::flush() returns a non-const reference, so there are no
further problems. And on a freshly created stream, it is a no-op.
Still, I think you'll agree that it isn't the most elegant or intuitive
solution.
What I usually do in such cases is create a wrapper class, which
contains it's own std::ostringstream, and provides a templated
member operator<< which forwards to the contained
std::ostringstream. Your function foo would take a const
reference to this—or what I offen do is have the destructor call
foo directly, so that the client code doesn't even have to worry about
it; it does something like:
log() << "number = " << 500;
The function log() returns an instance of the wrapper class (but see
below), and the (final) destructor of this class calls your function
foo.
There is one slight problem with this. The return value may be copied,
and destructed immediately after the copy. Which will wreck havoc with
what I just explained; in fact, since std::ostringstream isn't
copyable, it won't even compile. The solution here is to put all of the
actual logic, including the instance of std::ostringstream and the
destructor logic calling foo in a separate implementation class, have
the public wrapper have a boost::shared_ptr to it, and forward. Or
just reimplement a bit of the shared pointer logic in your class:
class LogWrapper
{
std::ostringstream* collector;
int* useCount;
public:
LogWrapper()
: collector(new std::ostringstream)
, useCount(new int(1))
{
}
~LogWrapper()
{
-- *useCount;
if ( *useCount == 0 ) {
foo( collector->str() );
delete collector;
delete useCount;
}
}
template<typename T>
LogWrapper& operator<<( T const& value )
{
(*collector) << value;
return *this;
}
};
Note that it's easy to extend this to support optional logging; just
provide a constructor for the LogWrapper which sets collector to
NULL, and test for this in the operator<<.
EDITED:
One other thing occurs to me: you'll probably want to check whether the
destructor is being called as a result of an exception, and not call
foo in that case. Logically, I'd hope that the only exception you
might get is std::bad_alloc, but there will always be a user who
writes something like:
log() << a + b;
where the + is a user defined overload which throws.
I would suggest you to use this utility struct:
struct stringbuilder
{
std::stringstream ss;
template<typename T>
stringbuilder & operator << (const T &data)
{
ss << data;
return *this;
}
operator std::string() { return ss.str(); }
};
And use it as:
void f(const std::string & s );
int main()
{
char const *const pc = "hello";
f(stringbuilder() << '{' << pc << '}' );
//this is my most favorite line
std::string s = stringbuilder() << 25 << " is greater than " << 5 ;
}
Demo (with few more example) : http://ideone.com/J995r
More on my blog : Create string on the fly just in one line
You could use a proxy object for this; this is a bit of framework, but if you want to use this notation in a lot of places then it may be worth it:
#include <iostream>
#include <sstream>
static void foo( std::string const &s )
{
std::cout << s << std::endl;
}
struct StreamProxy
{
std::stringstream stream;
operator std::string() { return stream.str(); }
};
template <typename T>
StreamProxy &operator<<( StreamProxy &s, T v )
{
s.stream << v;
return s;
}
static StreamProxy make_stream()
{
return StreamProxy();
}
int main()
{
foo( make_stream() << "number = " << 500 );
}
This program prints
number = 500
The idea is to have a little wrapper class which can be implicitely converted into a std::string. The << operator is simply forwarded to the contained std::stringstream. The make_stream() function is strictly speaking not necessary (you could also say StreamProxy(), but I thought it looks a bit nicer.
A couple of options other than the nice proxy solution just presented by Frerich Raabe:
Define a static string stream variable in the header that defines the logging function and use the comma operator in your invocation of the logging function so that this variable is passed rather than the ostream& returned by the stream insertion operator. You can use a logging macro to hide this ugliness. The problem with this solution is that it is a bit on the ugly side, but this is a commonly used approach to logging.
Don't use C++ I/O. Use a varargs C-style solution instead. Pass a format string as the first argument, with the remaining arguments being targets for that format string. A problem with this solution is that even if your compiler is smart enough to ensure that printf and its cousins are safe, the compiler probably won't know that this new function is a part of the printf family. Nonetheless, this is also a commonly used approach.
If you don't mind using macros functions, you can make the logging function accept const string&, and use the following macro
#define build_string(expr) \
(static_cast<ostringstream*>(&(ostringstream().flush() << expr))->str())
And suppose you foo has signature void foo(const string&), you only need the one-liner
foo(build_string("number = " << 500))
This was inspired by James Kanze's answer about static_cast and stringstream.flush. Without the .flush() the above method fails with unexpected output.
Please note that this method should not leak memory, as temporary values, whether in the pointer form or not, are still allocated on the stack and hence destroyed upon return.
Since you're converting to string anyways, why not
void foo(const std::string& s)
{
std::cout << "foo: " << s << std::endl;
}
...
std::stringstream ss;
ss << "number = " << 500;
foo(ss.str());
This is not possible. As the name ostream implies, it is used for output, for writing to it. You could change the parameter to stringstream&. This class has the method str() which returns a std::string for your use.
EDIT I did not read the issue with operator << returning ostream&. So I guess you cannot simply write your statements within the functions argument list but have to write it before.
You can create a small wrapper around std::ostringstream that will convert back to std::string on use, and have the function take a std::string const &. The first approach to this solution can be found in this answer to a different question.
On top of that, you can add support for manipulators (std::hex) if needed.