Printing either to console or to a string/stream - c++

I need a C++ function that dumps some text data (multiple lines) to the console:
void DumpData() const
{
std::cout << "My Data 1" << std::endl;
std::cout << "My Data 2" << std::endl;
}
This should be the default behaviour, however, it must also be possible to pass some other stream object that would be used instead of std::cout, something like this:
void DumpData(std::ostream& Stream = std::cout) const
{
Stream << "My Data 1" << std::endl;
Stream << "My Data 2" << std::endl;
}
Now to my questions:
What is the correct type I should use for the paramter (std::ostream& in this example)?
What is the default value, can I use = std::cout directly?
Moreover (3.), after the call to this function, if I pass my own stream object, I need to iterate over all strings in this stream line by line. What would be the best way to achieve this?

Why don't you just try it yourself?
Here's you code in Coliru for std::cout and std::stringstream as an example (constness of DumpData removed obviously):
#include <iostream>
#include <sstream>
void DumpData(std::ostream& Stream = std::cout)
{
Stream << "My Data 1" << std::endl;
Stream << "My Data 2" << std::endl;
}
int main() {
DumpData();
std::stringstream ss;
DumpData(ss);
std::string l;
while(std::getline(ss, l)) {
std::cout << l << std::endl;
}
return 0;
}
Output is what you expected.

1 and 2 are correct. Your other option is to use std::ostringstream, but since std::cout is a std::ostream you would need to define another function with this signature.
To iterate the custom output, I would convert the stream to a string, then use some kind of string splitting to read each line.

Adding to #Jay 's answer, you could use a template parameter to be able to use a variety of streams such as std::stringstream or a std::iostream as long as the template parameter supports the << operator.
template <typename T> // = decltype(something)
void DumpData(T& Stream = std::cout) const
{
Stream << "My Data 1" << std::endl;
Stream << "My Data 2" << std::endl;
}
You can take it one step further by ensuring the type T provided overloads the operator <<.
Also in some cases, certain (possibly custom) streams may not be able to support std::endl so it might be safer to default to using \n which is always nicer since it avoid unnecessary flushes.

Related

Deferring cout output until just prior to the next output

I have some C++ console programs that display progress information on the last line of output, at regular intervals.
This progress line is cleared prior to writing the next real output (or updated progress information); this could be from a number of different places in the source, and I'm currently clearing the progress line on each one, e.g.:
cout << clearline << "Some real output" << endl;
...
cout << clearline << "Some other real output" << endl;
...
cout << clearline << setw(4) << ++icount << ") " << ... << endl;
...
cout << clearline << "Progress info number " << ++iprog << flush;
Here, 'clearline' is some (system dependent) string like "\r\33[2K" which clears the current last line.
I would prefer something cleaner, that localises source changes to the actual line that's going to be cleared, like simply:
cout << "Progress info number " << ++iprog << flush << defer_clearline;
where 'defer_clearline' causes the writing of 'clearline' to be deferred until just prior to the next cout output, wherever and whatever that happens to be. I then wouldn't need to use 'clearline' on all the other lines.
I thought it might be possible to do this if 'defer_clearline' is a manipulator, and/or using xalloc() and iword().
But I've not managed to get anything that works.
Is it possible to do this sort of thing, and if so how?
2020-12-30: edited to include missing 'flush's.
You can pretty easily setup an std::cout wrapper:
// Declare the empty struct clear_line and instantiate the object cls
struct clear_line { } cls;
class out {
private:
std::ostream &strm = std::cout;
bool is_next_clear = false;
public:
template <typename T>
out& operator<<(const T& obj) {
if(is_next_clear) {
strm << std::endl << std::endl << std::endl; // clear logic
is_next_clear = false;
}
strm << obj;
return *this;
}
out& operator<<(const clear_line& _) {
is_next_clear = true;
return *this;
}
};
This pretty simply stores an is_next_clear bool for whether or not the next regular output should be cleared. Then, in the general case (the templated operator<<()), we run your clear logic and flip the is_next_clear flag if applicable. Then just output as usual.
Then, the operator<<() is overloaded for the case of a clear_line object. So if one of those is sent, we know to flip the is_next_clear flag, but not actually output anything.
Here's an example use:
int main() {
out o;
o << "Some real output" << cls;
o << "Some other real output";
return 0;
}
Here it is in action: https://ideone.com/0Dzwlv
If you want to use endl, you'll need to add a special overload for it as this answer suggests: https://stackoverflow.com/a/1134467/2602718
// this is the type of std::cout
typedef std::basic_ostream<char, std::char_traits<char> > CoutType;
// this is the function signature of std::endl
typedef CoutType& (*StandardEndLine)(CoutType&);
// define an operator<< to take in std::endl
out& operator<<(StandardEndLine manip)
{
// call the function, but we cannot return its value
manip(strm);
return *this;
}
Live example: https://ideone.com/ACUMOo

Processing all passed overloads at once

I'm tired of making up on the spot debug codes and including <iostream> in every single file. So I wanted to make myself a universal, self-contained and lightweight debug class, that I would just include in the header, and forget.
I want to use something along the lines of
#include "debug.hpp"
debug DBG;
DBG << "foo and" << " bar";
//Or even better, just include it and do debug() << "foo and" << " bar";
So, I wrote this:
#include <iostream>
#include <string>
#include <chrono>
#include <ctime>
class Debug
{
public:
Debug &operator<<(std::string arg_0)
{
auto tempTime = std::chrono::system_clock::to_time_t(
std::chrono::system_clock::now() );
auto timeString(ctime(&tempTime));
timeString = timeString.substr(timeString.find(':') - 2, 8);
std::cout << timeString << " >> " << arg_0 << '\n';
return *this;
}
};
But of course, this doesn't work because, as I've learned, every overload operator causes this function (is it still called a function?) to trigger separately. Creating:
hour:minute:second >> foo and
hour:minute:second >> bar
Any way I could pass everything at once after the first overload operator appears? Maybe as a stringstream? Also, I won't be only passing strings, but anything that I need, will this require me to manually create a separate overload function for every signle type that I may pass?
P.S: Cross-plaform solution is optional, but welcome (Currently developing on Linux)
You may return an other class to do the job, something like:
class Helper
{
public:
~Helper() { std::cout << "\n"; }
template<typename T>
friend Helper&& operator << (Helper&&h, const T& t) {
std::cout << t;
return std::move(h);
}
};
class Debug
{
public:
template<typename T>
friend Helper operator<<(Debug&, const T& t)
{
auto tempTime = std::chrono::system_clock::to_time_t(
std::chrono::system_clock::now() );
auto timeString{ctime(&tempTime)};
timeString = timeString.substr(timeString.find(':') - 2, 8);
std::cout << timeString << " >> " << t;
return Helper{};
}
};
Each time you call operator<<, your code prints the time stamp and \n. And that's the problem. To avoid that, you can print the time stamp in the constructor of Debug, and print \n in the destructor.
class Debug {
public:
Debug() {
auto tempTime = std::chrono::system_clock::to_time_t(
std::chrono::system_clock::now() );
std::string timeString(ctime(&tempTime));
timeString = timeString.substr(timeString.find(':') - 2, 8);
std::cout << timeString;
}
~Debug() {
std::cout << "\n";
}
Debug &operator<<(std::string arg_0) {
std::cout << " >> " << arg_0;
return *this;
}
};
In order to debug types other than string, you make operator<< a template:
template <typename T>
Debug &operator<<(T &&arg_0) {
std::cout << " >> " << std::forward<T>(arg_0);
return *this;
}
I see 2 design problems here:
You try to create stream-like object. It means that it doesn't know, when the line ends, until you send EOL to it. Without this information, it doesn't know when to add prefix to "your" line and print it. Consider the two following situation:
DBG << "foo and" << " bar";
and
DBG << "foo and";
... (a lot of code) ...
DBG << " bar";
They look exactly the same inside your Debug class, because:
DBG << "foo and" << " bar"; == (DBG.operator<<("foo and")).operator<<(" bar");
And this is the same as:
DBG.operator<<("foo and");
DBG.operator<<("bar");
So you have to decide how to define the end of the message you want to print (and when do you want to measure the time: At the beginning or at the end of the message?).
When do you want to flush your stream? You have to send std::endl or std::flush to std::cout to flush it. Sending "\n" does not flush std::cout (this is important difference between std::endl and "\n"). If you do not flush it, it may be printed several minutes/hours later (it will wait in a buffer). On the other hand frequent buffer flushing may be a performance killer in application producing large amount of text.
Try to define how your stream should behave when you send to it "\n", std::endl and std::flush (std::endl should be converted to "\n"+std::flush).
About other questions:
I would use simple template to "transfer" parameter of operator<<() to std::cout. It would allow to use your class for any type that can be printed by std::cout. To make things simpler you can define the operator<<() outside your class, eg.:
template<typename tParam>
Debug &operator<<(Debug& stream, tParam const & myParam)
{
...
return stream;
}

how to keep track of the current position in std::stringstream

I am writing a custom logger where I buffer my log messages in a std::stringstream and flush it to a file (std::ofstream) whenever the std::stringstream is big enough(to save some IO latency) . sincestd::stringstream doesn't have a .size() method, I use seekg and tellg :
template <typename T>
MyClass & operator<< (const T& val)
{
boost::unique_lock<boost::mutex> lock(mutexOutput);
output << val; //std::stringstream output;
output.seekg(0, std::ios::end);
if(output.tellg() > 1048576/*1MB*/){
flushLog();
}
return *this;
}
Problem:
It seems to me that, whenever I invoke this method, it uses seekg to start counting the bytes from the beginning all the way to the end and get the size using tellg. I came up with this design to save some IO time in the first place, but: isn't this continuous counting impose a larger cost(if the number of calls to this method is high and log messages are small as in most of the cases)?
is there a better way to do this?
And a side question: is 1MB a good number for buffer size in a normal nowadays computers?
Thank you
You can just use ostringstream::tellp() to get the length of the string. Here's an example lifted from http://en.cppreference.com/w/cpp/io/basic_ostream/tellp.
#include <iostream>
#include <sstream>
int main()
{
std::ostringstream s;
std::cout << s.tellp() << '\n';
s << 'h';
std::cout << s.tellp() << '\n';
s << "ello, world ";
std::cout << s.tellp() << '\n';
s << 3.14 << '\n';
std::cout << s.tellp() << '\n' << s.str();
}
Output:
0
1
13
18
hello, world 3.14

multiple threads writing to std::cout or std::cerr

I have OpenMP threads that write to the console via cout and cerr. This of course is not safe, since output can be interleaved. I could do something like
#pragma omp critical(cerr)
{
cerr << "my variable: " << variable << endl;
}
It would be nicer if could replace cerr with a thread-safe version, similar to the approach explained in the valgrind DRD manual (http://valgrind.org/docs/manual/drd-manual.html#drd-manual.effective-use) which involves deriving a class from std::ostreambuf. Ideally in the end I would just replace cerr with my own threaded cerr, e.g. simply:
tcerr << "my variable: " << variable << endl;
Such a class could print to the console as soon as it encounters an "endl". I do not mind if lines from different threads are interleaved, but each line should come only from one thread.
I do not really understand how all this streaming in C++ works, it is too complicated. Has anybody such a class or can show me how to create such a class for that purpose?
As others pointed out, in C++11, std::cout is thread-safe.
However if you use it like
std::cout << 1 << 2 << 3;
with different threads, the output can still be interleaved, since every << is a new function call which can be preceeded by any function call on another thread.
To avoid interleaving without a #pragma omp critical - which would lock everything - you can do the following:
std::stringstream stream; // #include <sstream> for this
stream << 1 << 2 << 3;
std::cout << stream.str();
The three calls writing 123 to the stream are happening in only one thread to a local, non-shared object, therefore aren't affected by any other threads. Then, there is only one call to the shared output stream std::cout, where the order of items 123 is already fixed, therefore won't get messed up.
You can use an approach similar to a string builder. Create a non-template class that:
offers templated operator<< for insertion into this object
internally builds into a std::ostringstream
dumps the contents on destruction
Rough approach:
class AtomicWriter {
std::ostringstream st;
public:
template <typename T>
AtomicWriter& operator<<(T const& t) {
st << t;
return *this;
}
~AtomicWriter() {
std::string s = st.str();
std::cerr << s;
//fprintf(stderr,"%s", s.c_str());
// write(2,s.c_str(),s.size());
}
};
Use as:
AtomicWriter() << "my variable: " << variable << "\n";
Or in more complex scenarios:
{
AtomicWriter w;
w << "my variables:";
for (auto & v : vars) {
w << ' ' << v;
}
} // now it dumps
You will need to add more overloads if you want manipulators, you can use write better than fprintf for the atomic write in the destructor, or std::cerr, you can generalize so that the destination is passed to the constructor (std::ostream/file descriptor/FILE*),
I don't have enough reputation to post a comment, but I wanted to post my addition to the AtomicWriter class to support std::endl and allow for other streams to be used besides std::cout. Here it is:
class AtomicWriter {
std::ostringstream st;
std::ostream &stream;
public:
AtomicWriter(std::ostream &s=std::cout):stream(s) { }
template <typename T>
AtomicWriter& operator<<(T const& t) {
st << t;
return *this;
}
AtomicWriter& operator<<( std::ostream&(*f)(std::ostream&) ) {
st << f;
return *this;
}
~AtomicWriter() { stream << st.str(); }
};
Put the following code in header file atomic_stream_macro.h
#ifndef atomic_stream_macro_h
#define atomic_stream_macro_h
#include <mutex>
/************************************************************************/
/************************************************************************/
extern std::mutex print_mutex;
#define PRINT_MSG(out,msg) \
{ \
std::unique_lock<std::mutex> lock (print_mutex); \
\
out << __FILE__ << "(" << __LINE__ << ")" << ": " \
<< msg << std::endl; \
}
/************************************************************************/
/************************************************************************/
#endif
Now the macro can be used from a file as follows.
#include <atomic_stream_macro.h>
#include <iostream>
int foo (void)
{
PRINT_MSG (std::cout, "Some " << "Text " << "Here ");
}
Finally, in the main.cxx, declare the mutex.
#include <mutex>
std::mutex print_mutex;
int main (void)
{
// launch threads from here
}
You could do it by inheriting std::basic_streambuf, and override the correct functions to make it threadsafe. Then use this class for your stream objects.

c++ custom output stream with indentation

I'm having some trouble trying to implement a custom stream class to generate nicely indented code in an output file. I've searched online extensively but there doesn't seem to be a consensus on the best way to achieve this. Some people talk about deriving the stream, others talk about deriving the buffer, yet others suggest the use of locales/facets etc.
Essentially, I'm finding myself writing a lot of code like this:
ofstream myFile();
myFile.open("test.php");
myFile << "<html>" << endl <<
"\t<head>" << endl <<
"\t\t<title>Hello world</title>" << endl <<
"\t</head>" << endl <<
"</html>" << endl;
When the tabs start to add up it looks horrible, and it seems like it would be nice to have something like this:
ind_ofstream myFile();
myFile.open("test.php");
myFile << "<html>" << ind_inc << ind_endl <<
"<head>" << ind_inc << ind_endl <<
"<title>Hello world</title>" << ind_dec << ind_endl <<
"</head>" << ind_dec << ind_endl <<
"</html>" << ind_endl;
i.e. create a derived stream class which would keep track of its current indent depth, then some manipulators to increase/decrease the indent depth, and a manipulator to write a newline followed by however many tabs.
So here's my shot at implementing the class & manipulators:
ind_ofstream.h
class ind_ofstream : public ofstream
{
public:
ind_ofstream();
void incInd();
void decInd();
size_t getInd();
private:
size_t _ind;
};
ind_ofstream& inc_ind(ind_ofstream& is);
ind_ofstream& dec_ind(ind_ofstream& is);
ind_ofstream& endl_ind(ind_ofstream& is);
ind_ofstream.cpp
ind_ofstream::ind_ofstream() : ofstream() {_ind = 0;}
void ind_ofstream::incInd() {_ind++;}
void ind_ofstream::decInd() {if(_ind > 0 ) _ind--;}
size_t ind_ofstream::getInd() {return _ind;}
ind_ofstream& inc_ind(ind_ofstream& is)
{
is.incInd();
return is;
}
ind_ofstream& dec_ind(ind_ofstream& is)
{
is.decInd();
return is;
}
ind_ofstream& endl_ind(ind_ofstream& is)
{
size_t i = is.getInd();
is << endl;
while(i-- > 0) is << "\t";
return is;
}
This builds, but doesn't generate the expected output; any attempt to use the custom manipulators results in them being cast to a boolean for some reason and "1" written to the file. Do I need to overload the << operator for my new class? (I haven't been able to find a way of doing this that builds)
Thanks!
p.s.
1) I've omitted the #includes, using namespace etc from my code snippets to save space.
2) I'm aiming to be able to use an interface similar to the one in my second code snippet. If after reading the whole post, you think that's a bad idea, please explain why and provide an alternative.
The iostreams support adding custom data to them, so you don't need to write a full derived class just to add an indentation level that will be operated on by manipulators. This is a little-known feature of iostreams, but comes in handy here.
You would write your manipulators like this:
/* Helper function to get a storage index in a stream */
int get_indent_index() {
/* ios_base::xalloc allocates indices for custom-storage locations. These indices are valid for all streams */
static int index = ios_base::xalloc();
return index;
}
ios_base& inc_ind(ios_base& stream) {
/* The iword(index) function gives a reference to the index-th custom storage location as a integer */
stream.iword(get_indent_index())++;
return stream;
}
ios_base& dec_ind(ios_base& stream) {
/* The iword(index) function gives a reference to the index-th custom storage location as a integer */
stream.iword(get_indent_index())--;
return stream;
}
template<class charT, class traits>
basic_ostream<charT, traits>& endl_ind(basic_ostream<charT, traits>& stream) {
int indent = stream.iword(get_indent_index());
stream.put(stream.widen('\n');
while (indent) {
stream.put(stream.widen('\t');
indent--;
}
stream.flush();
return stream;
}
I have combined Bart van Ingen Schenau's solution with a facet, to allow pushing and popping of indentation levels to existing output streams. The code is available on github: https://github.com/spacemoose/ostream_indenter, and there's a more thorough demo/test in the repository, but basically it allows you to do the following:
/// This probably has to be called once for every program:
// http://stackoverflow.com/questions/26387054/how-can-i-use-stdimbue-to-set-the-locale-for-stdwcout
std::ios_base::sync_with_stdio(false);
std::cout << "I want to push indentation levels:\n" << indent_manip::push
<< "To arbitrary depths\n" << indent_manip::push
<< "and pop them\n" << indent_manip::pop
<< "back down\n" << indent_manip::pop
<< "like this.\n" << indent_manip::pop;
To produce:
I want to push indentation levels:
To arbitrary depths
and pop them
back down
like this.
I had to do a kind of nasty trick, so I'm interested in hearing feedback on the codes utility.