{fmt} equivalent to cout.rdbuf? - c++

I have a unit test that verifies a function by reading the buffer sent by the function:
template <typename Manifold>
void print_manifold(Manifold const& manifold)
try
{
std::cout << "Manifold has " << manifold.N0() << " vertices and "
<< manifold.N1() << " edges and " << manifold.N2() << " faces and "
<< manifold.N3() << " simplices.\n";
// fmt::print(
// "Manifold has {} vertices and {} edges and {} faces and {}
// simplices.\n", manifold.N0(), manifold.N1(), manifold.N2(),
// manifold.N3());
}
catch (...)
{
std::cerr << "print_manifold() went wrong ...\n";
throw;
} // print_manifold
And:
SCENARIO("Printing results", "[utility]")
{
// redirect std::cout
stringstream buffer;
cout.rdbuf(buffer.rdbuf());
GIVEN("A Manifold3")
{
Manifold3 const manifold(640, 4);
WHEN("We want to print statistics on a manifold.")
{
THEN("Statistics are successfully printed.")
{
print_manifold(manifold);
CHECK_THAT(buffer.str(), Catch::Contains("Manifold has"));
}
}
}
Is there a way to capture the output generated by fmt::print going to stdout?
When I comment out the cout code and uncomment the fmt code, I get the buffer produced by previous instances of cout <<.

This is more of a C stdio than {fmt} question but you can redirect stdout to a pipe and read the output from it as described in the answers to Redirecting stdout to pipe in C. This is not a great unit test though because it depends on the global state but your current test has the same problem.

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

Logging function which uses operator <<

I'd like to write a function for logging which should be used like this:
log(__FILE__) << "My message containing integer: " << 123 << " and double: " << 1.2;
This should print the following line, add endl and flush immediately:
main.cpp: My message containing integer: 123 and double: 1.2
My (simplified) attempt for the implementation of the function:
class Writer
{
public:
template<typename T>
Writer & operator<<(T t)
{
cout << t << endl;
cout.flush();
return (*this);
}
};
Writer log(const char* fileName)
{
cout << fileName << ": ";
return Writer();
}
int main(int argc, const char *argv[])
{
log(__FILE__) << "My message containing integer: " << 123 << "and double: " << 1.2;
return 0;
}
My problem is that because of L-R associativity of the operator<< the output is:
main.cpp: My message containing integer:
123
and double:
1.2
Is there any way how to implement the function or is my requirement for its usage unrealizable?
Ideally I'd like to use plain C++03 (i.e. no C++11 features, boost and non-standard libraries).
L-R associativity is not related to your problem (if you talk about line breaks). The problem is because you use endl after each write. You don't need it (and if you do that, then you don't need flush, because endl already flushes the output).
The easy solution to your problem:
class Writer
{
public:
template<typename T>
Writer & operator<<(T t)
{
cout << t;
return (*this);
}
~Writer()
{
try {
cout << endl;
}
catch (...) {
// You have to make sure that no
// exception leaves destructor
}
}
};
It is also worth to notice, that your approach is not really scalable: it is impossible to use your code in multi-threaded environment. Assume that two threads are writing into your logging:
Thread 1: log(__FILE__) << "a" << "b" << "c";
Thread 2: log(__FILE__) << "a" << "b" << "c";
Here you can easily get a message "aabbcc\n\n" in your logfile, which is highly undesirable.
In order to avoid that, you can have a static mutex object inside log() function, which you pass into Writer constructor. Then you have to lock it in the constructor and unlock it in the destructor. It will guarantee the synchronization of concurrent writing of different entries.

Optionally print to stdout at runtime

I have output in a C++ program that I only want to see if a "verbose" option is specified at runtime. I've found lots of methods to use preprocessor #define statements to control debugging output when compiling, but I can't find any ways to do this at runtime short of wrapping every cout in if(verbose).
In pseudocode, I'd like to transform:
if(verbose)
cout << "Some text: " << variable << endl;
...
if(verbose)
cout << "Other text: " << var << endl;
Into:
if(verbose)
//block cout
cout << "Some text: " << variable << endl;
cout << "Other text: " << var << endl;
Is there some way to optionally redefine cout at runtime so those lines silently print nothing? Better yet would be a more flexible approach that allows some output while blocking others.
You can simply bind a stream object reference to different streams depending on verbose:
ostream& vout = (verbose? cout : nullstream);
Then use vout for all the output that should only appear when verbose.
Of course you need to define nullstream first; that involves defining a streambuf derived class.
I'm not sure whether you're in the process of writing a program, or whether you already have a program you want to disable output for. Generally, when you're writing software with debugging output, you'll want to create some sort of logging class to help you control when output occurs and where it goes (e.g., to a file, to stdout, to stderr, etc.). An example of a simple one would be:
#include <iostream>
class Logger {
public:
Logger(bool enabled) : enabled(enabled) { }
void setEnabled(bool enabled) { this->enabled = enabled; }
template<typename T> Logger& operator<<(T const& t)
{
if (enabled)
std::cout << t;
return *this;
}
// If you'd like manipulator support (e.g., for std::endl)
Logger& operator<<(std::ostream& (*manipulator)(std::ostream&))
{
if (enabled)
std::cout << manipulator;
return *this;
}
private:
bool enabled;
};
int main()
{
Logger log(true);
log << "Hello, " << "World!" << 123; // Prints Hello, World!123
log.setEnabled(false);
log << "Hello, " << "World!" << 123; // Prints nothing
}
Alternatively, you could redirect cout, as others have mentioned, or even just simply redirect your program's output to /dev/null on the command line:
./myProgram > /dev/null

C++ Read from file to vector

I'm trying to convert a string streamed phone lookup program into file streamed.. I'm missing something, but I'm stuck.. what members can I use in the ofstream process to get this working?
ofstream& process (ofstream &os, vector<PersonInfo> people)
{
// for each entry in people
for (vector<PersonInfo>::const_iterator entry = people.begin();
entry != people.end(); ++entry) {
ofstream formatted, badNums; // objects created on each loop
// for each number
for (vector<string>::const_iterator nums = entry->phones.begin();
nums != entry->phones.end(); ++nums) {
if (!valid(*nums)) {
badNums << " " << *nums; // string in badNums
} else
// ``writes'' to formatted's string
formatted << " " << format(*nums);
}
if (badNums.empty()) // there were no bad numbers
os << entry->name << " " // print the name
<< formatted.str() << endl; // and reformatted numbers
else // otherwise, print the name and bad numbers
cerr << "input error: " << entry->name
<< " invalid number(s) " << badNums.str() << endl;
}
return os;
}
First, you don't want an ofstream, except at the point you're opening
the file (creating the instance). The output stream interface is
defined by std::ostream; std::ofstream derives from this, as does
std::ostringstream (output can become an std::string), and in most
applications, a couple of others written by the local programmers. In
your case (if I've understood the problem correctly), what you want is:
std::ostream& process( std::ostream& os,
std::vector<PersonInfo> const& people )
// Note the use of a const reference above. No point
// in copying the entire vector if you're not going to
// modify it.
{
for ( std::vector<PersonInfo>::const_iterator entry = people.begin();
entry != people.end();
++ entry ) {
std::ostringstream formatted;
std::ostringstream badNums;
// ...
if ( badNums.str().empty() ) {
os << ... << formatted.str() << std::endl;
} else {
os << ... << badNums.str() << std::endl;
}
}
return os;
}
Note the different types: std::ostream formats output, independently
of the destination type. std::ofstream derives from it, and provides
a file as destination. std::ostringstream derives from it, and
provides a std::string as destination type. And the std::ostream
takes a std::streambuf* as argument, and you provide the destination
type.
You never associate a file with ostream, so the compiler doesn't know what to do with the data you write into it.
ofstream& process (ofstream &os, vector<PersonInfo> people)
{
os.open("Data.txt"); //open file to be used
if(!os.is_open())
std::cerr << "Error opening file!\n";
//rest of code goes here
}
EDIT: after reading through your program again, i noticed you're using ofstream wrong. Ofstream is for opening and writing FILES.The program has a lot of syntax and logical errors i would read up on it more here.
It looks like you don't need to use ofstreams for the internal parts of this function. In fact you don't need to use streams at all, a std::string would do:
ofstream& process (ofstream &os, vector<PersonInfo> people)
{
// for each entry in people
for (vector<PersonInfo>::const_iterator entry = people.begin();
entry != people.end(); ++entry) {
string formatted, badNums; // objects created on each loop
// for each number
for (vector<string>::const_iterator nums = entry->phones.begin();
nums != entry->phones.end(); ++nums) {
if (!valid(*nums)) {
badNums += " " + *nums; // string in badNums
} else
// ``writes'' to formatted's string
formatted += " " + format(*nums);
}
if (badNums.empty()) // there were no bad numbers
os << entry->name << " " // print the name
<< formatted << endl; // and reformatted numbers
else // otherwise, print the name and bad numbers
cerr << "input error: " << entry->name
<< " invalid number(s) " << badNums << endl;
}
return os;
}

How to make thread safe Log class that supports `<<` operations?

So I have such log class:
#include <iostream>
#include <sstream>
#include <boost/circular_buffer.hpp>
#include <boost/foreach.hpp>
class FlushInternal;
class Log
{
public:
static FlushInternal* endl;
Log(int log_length)
{
i = 0;
messages_buffer = new boost::circular_buffer<std::string>(log_length);
}
template <class T>
Log &operator<<(const T &v)
{
current_message << v;
return *this;
}
Log &operator<<(std::ostream&(*f)(std::ostream&))
{
current_message << *f;
return *this;
}
Log &operator<<(FlushInternal*)
{
++i;
messages_buffer->push_back(current_message.str());
clean_stringstream(current_message);
is_filled();
return *this;
}
boost::circular_buffer<std::string> *messages_buffer;
private:
int i;
std::stringstream current_message;
void is_filled()
{
if (i >= messages_buffer->capacity())
{
i = 0;
BOOST_FOREACH(std::string s, *messages_buffer)
{
std::cout << ++i << ": " << s << " ;" << std::endl;
}
i = 0;
}
}
void clean_stringstream(std::stringstream &message)
{
message.flush();
message.clear();
message.seekp(0);
message.str("");
}
};
FlushInternal* Log::endl = 0;
And I can Use it like this:
#include <log.h>
int main()
{
Log l(2);
l << "message one: " << 1 << Log::endl;
l << "message two:" << " " << 2 << Log::endl;
l << "message " << "three: " << 3 << Log::endl;
l << "message" << " " << "four: " << 4 << Log::endl;
std::cin.get();
}
This would output:
1: message one: 1 ;
2: message two: 2 ;
1: message three: 3 ;
2: message four: 4 ;
As you can see I can have as many << as I want inside each log message. I want to be capable to use one instance of Log class from many threads at the same time. So I would have something like (pseudocode that compiles, runs but traces nothing.):
#include <boost/thread.hpp>
#include <log.h>
Log *l;
void fun_one()
{
*l << "message one: " << 1 << Log::endl;
*l << "message two:" << " " << 2 << Log::endl;
}
void fun_two()
{
*l << "message " << "three: " << 3 << Log::endl;
*l << "message" << " " << "four: " << 4 << Log::endl;
}
int main()
{
l = new Log(2);
boost::thread(fun_one);
boost::thread(fun_two);
std::cin.get();
}
So as you can see I want messages to be inserted into log in multythreaded function. Lo I wonder - how to make my log cclass support this?
The approach linked by trojanfoe is pretty much the canonical one. Basically create some temporary thing for the leftmost << operator, accumulate everything, and output the message in the destructor for the temporary thing.
The only question is the exact mechanics of this accumulator. The example used ostringstream, but I've seen the ofstream for the log file used directly as well (requires locking to ensure the output ends up on one line).
Creating ostringstreams is relatively expensive on some platforms, because they may need to lock and copy some internal locale related things. You could re-implement also the << operator for interesting types, but I'd test the ostringstream approach first.
A useful optimization is determine at the point of the construction of the temporary whether the trace will be emitted (e.g., whether tracing is enabled at that particular level), and not create the guts of the temporary at all in that case - all the insertion operations will be no-ops.
Here's one approach:
http://drdobbs.com/cpp/201804215
It basically creates a new ostringstream object each time you perform logging, which makes it thread safe. I can't say I'm that keen on that, as it seems a little clumsy to me.
You might have a look at the Qt logging classes as they support the << operator, however I'm not sure about thread safety.