Hello,
I am importing a library in my code which is verbose in its standard output. I don't want to modify the imported library but I still need to keep my standard out as clean as possible. Is there a way to suppress the stdout from the imported library only, while still making my own outputs to stdout?
So in your case, set the failbit before calling the library functions, and then clear it once it completes the call. If this is happening in some asynchronous manner, you might need to be a bit more clever.
There may be other OS-level tricks to explore if that doesn't work, but it's a good start.
For example on Linux you might be able to use dup2 to set stdout to be null? https://man7.org/linux/man-pages/man2/dup.2.html
I've never heard of such a thing, although it's hard for me to prove a negative.
30.7.5.2.1 Common requirements [ostream.formatted.reqmts] 1 Each formatted output function begins execution by constructing an object of class sentry. If this object
returns true when converted to a value of type bool, the function endeavors to generate the requested
output. If the generation fails, then the formatted output function does setstate(ios_base::failbit),
which might throw an exception. If an exception is thrown during output, then ios::badbit is turned on
in *this’s error state. If (exceptions()&badbit) != 0 then the exception is rethrown. Whether or not
an exception is thrown, the sentry object is destroyed before leaving the formatted output function. If no
exception is thrown, the result of the formatted output function is *this.
2 The descriptions of the individual formatted output functions describe how they perform output and do not
mention the sentry object.
The functions for output seems to use wording like "if possible".
basic_ostream<charT, traits>& put(char_type c); 2 Effects: Behaves as an unformatted output function (as described above). After constructing a sentry object, inserts the character c, if possible.
Is it possible one of the reasons why the 3rd party library is so vomitous might be for diagnostic purposes? Such as when compiling as debug? Or defining/not defining some library flag to reduce/set the amount of output?
Without knowing what the library being used makes it nigh um-possible to give an answer that isn't 100% pure unadulterated "pulled out of one's arse" ideas.
I think library code writing to std::cout or std::cerr is really bad practice. For example, many command-line programs write output to std::cout that is supposed to be pipe'd to the std::cin of the next program in the chain. A third-party library writing to std::cout unsolicited has a great potential of corrupting the output!
Anyway, you could try:
1 2 3 4 5 6 7
std::ostringstream local;
auto cout_buff = std::cout.rdbuf();
std::cout.rdbuf(local.rdbuf());
/* call library function here !!! */
std::cout.rdbuf(cout_buff);
(Note: Any "hack" that temporarily disables/redirects std::cout around library calls is not thread-safe)
If there is a way to suppress/reduce the volume of the output via some form of a program switch, like a #define, then writing to std::cerr isn't all that bad, if rather amateurish.
@see17
You might take a look at the documentation of the library. Usually there is a #define to switch this output on/offf
There might also be a difference with debug/release version.
> Is there a way to suppress the stdout from the imported library only,
> while still making my own outputs to stdout?
We can create an output stream of our own which sends its output to stdout.
And then redirect the output of std::cout (which the library, presumably, uses) to a file.
For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#include <iostream>
#include <fstream>
int main()
{
// we use mycout to send our output to stdout
std::ostream mycout( std::cout.rdbuf() ) ;
// the library uses std::cout; it sends the output to a file
std::filebuf fbuf ;
fbuf.open( "lib_stdout.txt", std::ios::out ) ; // open a file for output
std::cout.rdbuf( std::addressof(fbuf) ) ; // and let std::cout send its output to this file
mycout << "our output goes to stdout\n" ;
std::cout << "library output goes to the file 'lib_stdout.txt'\n" ;
// once we are done, restore the original behaviour of std::cout
std::cout.rdbuf( mycout.rdbuf() ) ;
}
If we must use the same stream std::cout both in our code and the library, things get a little more involved: