I have heard several times, that one should avoid plain writes to std::cout. (Is this correct?) However, I did not find good examples of how to achieve this. What I came up with so far is this:
#include <iostream>
class Logger {
std::ostream os;
auto RdBuffer( bool const decision ) { return decision ? std::cout.rdbuf() : nullptr; }
public:
explicit Logger( bool const use_cout = true ) : os( RdBuffer( use_cout ) ) {}
void Print() {
os << "Ptinting" << std::endl;
}
};
It allows me to write to std::cout if wanted, or stays silent otherwise. It seems to work, but I'm not sure this is the correct approach. What worries me in particular is the initialization with the nullptr and the consecutive writing to it in case the bool is set to false.
Is this going in the right direction? I'm particular interested in modern C++ ways of achieving this. So C++11 or newer answers are greatly appreciated.
Edit: Corrected typo in code.
I have heard several times, that one should avoid plain writes to std::cout. Is this correct?
No. It is accepted practice to write output to the standard output stream - unless you're in some embedded setting, or using an exotic OS where output is handled very differently.
The operating system and other processes will expect output to be written to that stream, or to whatever it represents (e.g. the standard output file handle on Unix-like systems).
What I came up with so far is this [piece of code here]
Well,
There are several popular logging libraries for C++. Here's a question about that over at SoftwareRecs.SX. No need to re-invenet the wheel if what you want is to do logging.
As #largest_prime_is_463035818 suggests in their comment, it's often good enough to just pass around an std::ostream and write to that. And when you want to not write anywhere - that's possible too; read these SO questions:
Standard no-op output stream
Printing to nowhere with ostream
Having said all this - there are some cases in which you might legitimately want to have std::cout itself be redirected to print somewhere else. I don't think that's covered by the standard, though.
Related
Suppose there are 30 numbers I had to input into an executable, because of the large amount of input, it is not reasonable to input them via command line. One standard way is to save them into a single XML file and use XML parser like tinyxml2 to parse them. The problem is if I use tinyxml2 to parse the input directly I will have a very bloated main function, which seems to contradict the common good practice.
For example:
int main(int argc, char **argv){
int a[30];
tinyxml2::XMLDocument doc_xml;
if (doc_xml.LoadFile(argv[1])){
std::cerr << "failed to load input file";
}
else {
tinyxml2::XMLHandle xml(&doc_xml);
tinyxml2::XMLHandle a0_xml =
xml.FirstChildElement("INPUT").FirstChildElement("A0");
if (a0_xml.ToElement()) {
a0_xml.ToElement()->QueryIntText(&a[0]);
}
else {
std::cerr << "A0 missing";
}
tinyxml2::XMLHandle a1_xml =
xml.FirstChildElement("INPUT").FirstChildElement("A1");
if (a1_xml.ToElement()) {
a1_xml.ToElement()->QueryIntText(&a[1]);
}
else {
std::cerr << "A1 missing";
}
// parsing all the way to A29 ...
}
// do something with a
return 0;
}
But on the other hand, if I write an extra class just to parse these specific type of input in order to shorten the main function, it doesn't seem to be right either, because this extra class will be useless unless it's used in conjunction with this main function since it can't be reused elsewhere.
int main(int argc, char **argv){
int a[30];
ParseXMLJustForThisExeClass ParseXMLJustForThisExeClass_obj;
ParseXMLJustForThisExeClass_obj.Run(argv[1], a);
// do something with a
return 0;
}
What is the best way to deal with it?
Note, besides reading XML files you can also pass lots of data through stdin. It's pretty common practice to use e.g. mycomplexcmd | hexdump -C, where hexdump is reading from stdin through the pipe.
Now up to the rest of the question: there's a reason to go with the your multiple-functions example (here it's not very important whether they're constructors or usual functions). It's pretty much the same as why would you want any function to be smaller — readability. That said, I don't know about the "common good practice", and I've seen many terminal utilities with very big main().
Imagine someone new is reading 1-st variant of main(). They'd be going through the hoops of figuring out all these handles, queries, children, parents — when all they wanted is to just look at the part after // do something with a. It's because they don't know if it's relevant to their problem or not. But in the 2-nd variant they'll quickly figure it out "Aha, it's the parsing logic, it's not what I am looking for".
That said, of course you can break the logic with detailed comments. But now imagine something went wrong, someone is debugging the code, and they pinned down the problem to this function (alright, it's funny given the function is main(), maybe they just started debugging). The bug turned out to be very subtle, unclear, and one is checking everything in the function. Now, because you're dealing with mutable language, you'd often find yourself in situation where you think "oh, may be it's something with this variable, where it's being changed?"; and you first look up every use of the variable through this large function, then conditions that could lead to blocks where it's changed; then you figuring out what does this another big block, relevant to the condition, that could've been extracted to a separate function, what variables are used in there; and to the moment you figured out what it's doing you already forgot half of what you were looking before!
Of course sometimes big functions are unavoidable. But if you asked the question, it's probably not your case.
Rule of thumb: you see a function doing two different things having little in common, you want to break it to 2 separate functions. In your case it's parsing XML and "doing something with a". Though if that 2-nd part is a few lines, probably not worth extracting — speculate a bit. Don't worry about the overhead, compilers are good at optimizing. You can either use LTO, or you can declare a function in .cpp file only as static (non-class static), and depending on optimization options a compiler may inline the code.
P.S.: you seem to be in the state where it's very useful to learn'n'play with some Haskell. You don't have to use it for real serious projects, but insights you'd get can be applied anywhere. It forces you into better design, in particular you'd quickly start feeling when it's necessary to break a function (aside of many other things).
Is there a canonical / public / free implementations variant of std::stringstream where I don't pay for a full string copy each time I call str()? (Possibly through providing a direct c_str() member in the osteam class?)
I've found two questions here:
C++ stl stringstream direct buffer access (Yeah, it's basically the same title, but note that it's accepted answer doesn't fit this here question at all.)
Stream from std::string without making a copy? (Again, accepted answer doesn't match this question.)
And "of course" the deprecated std::strstream class does allow for direct buffer access, although it's interface is really quirky (apart from it being deprecated).
It also seems one can find several code samples that do explain how one can customize std::streambuf to allow direct access to the buffer -- I haven't tried it in practice, but it seems quite easily implemented.
My question here is really two fold:
Is there any deeper reason why std::[o]stringstream (or, rather, basic_stringbuf) does not allow direct buffer access, but only access through an (expensive) copy of the whole buffer?
Given that it seems easy, but not trivial to implement this, is there any varaint available via boost or other sources, that package this functionality?
Note: The performance hit of the copy that str() makes is very measurable(*), so it seems weird to have to pay for this when the use cases I have seen so far really never need a copy returned from the stringstream. (And if I'd need a copy I could always make it at the "client side".)
(*): With our platform (VS 2005), the results I measure in the release version are:
// tested in a tight loop:
// variant stream: run time : 100%
std::stringstream msg;
msg << "Error " << GetDetailedErrorMsg() << " while testing!";
DoLogErrorMsg(msg.str().c_str());
// variant string: run time: *** 60% ***
std::string msg;
((msg += "Error ") += GetDetailedErrorMsg()) += " while testing!";
DoLogErrorMsg(msg.c_str());
So using a std::string with += (which obviously only works when I don't need custom/number formatting is 40% faster that the stream version, and as far as I can tell this is only due to the complete superfluous copy that str() makes.
I will try to provide an answer to my first bullet,
Is there any deeper reason why std::ostringstream does not allow direct buffer access
Looking at how a streambuf / stringbuf is defined, we can see that the buffer character sequence is not NULL terminated.
As far as I can see, a (hypothetical) const char* std::ostringstream::c_str() const; function, providing direct read-only buffer access, can only make sense when the valid buffer range would always be NULL terminated -- i.e. (I think) when sputc would always make sure that it inserts a terminating NULL after the character it inserts.
I wouldn't think that this is a technical hindrance per se, but given the complexity of the basic_streambuf interface, I'm totally not sure whether it is correct in all cases.
As for the second bullet
Given that it seems easy, but not trivial to implement this, is there
any variant available via boost or other sources, that package this
functionality?
There is Boost.Iostreams and it even contains an example of how to implement an (o)stream Sink with a string.
I came up with a little test implementation to measure it:
#include <string>
#include <boost/iostreams/stream.hpp>
#include <libs/iostreams/example/container_device.hpp> // container_sink
namespace io = boost::iostreams;
namespace ex = boost::iostreams::example;
typedef ex::container_sink<std::wstring> wstring_sink;
struct my_boost_ostr : public io::stream<wstring_sink> {
typedef io::stream<wstring_sink> BaseT;
std::wstring result;
my_boost_ostr() : BaseT(result)
{ }
// Note: This is non-const for flush.
// Suboptimal, but OK for this test.
const wchar_t* c_str() {
flush();
return result.c_str();
}
};
In the tests I did, using this with it's c_str()helper ran slightly faster than a normal ostringstream with it's copying str().c_str() version.
I do not include measuring code. Performance in this area is very brittle, make sure to measure your use case yourself! (For example, the constructor overhead of a string stream is non-negligible.)
I have a question re my C++ class design. Often I face little issues like this and I'd like some advice as to what is better accepted.
I have some class which monitors the temperature of some device over UDP. If the device receives a packet of data, it is to print "x\n" to stdout to show that it received something. Then it is to check the data in that packet and verify that the data doesn't show that the temperature of the device is too high. If it is too high, I must call some function. If it isn't, I must call some other function.
I'm not sure if I should do this:
enum temperature {TEMPERATURE_FINE, TEMPERATURE_EXCEEDED};
int main(int argc, char* argv[])
{
std::vector<std::string> args(argv+1, argv + argc);
if(!args.size())
cout << "No parameters entered.\n";
else
{
CTemperatureMonitor tempMonitor(args);
if(tempMonitor.MonitorTemperature() == TEMPERATURE_EXCEEDED)
tempMonitor.ActivateAlarm();
else
tempMonitor.DisableAlarm();
}
return 0;
}
where tempMonitor.MonitorTemperature() calls std::cout << "x\n". So std::cout << "x\n" is built into the class.
Or:
enum temperature {TEMPERATURE_FINE, TEMPERATURE_EXCEEDED};
int main(int argc, char* argv[])
{
std::vector<std::string> args(argv+1, argv + argc);
if(!args.size())
cout << "No parameters entered.\n";
else
{
CTemperatureMonitor tempMonitor(args);
temperature tempExceeded = tempMonitor.MonitorTemperature();
std::cout << "x\n";
if(tempExceeded == TEMPERATURE_EXCEEDED)
tempMonitor.ActivateAlarm();
else
tempMonitor.DisableAlarm();
}
return 0;
}
where std::cout << "x\n" is not included in the class.
The std::cout << "x\n" must occur before calling CTemperatureMonitor::ActivateAlarm() and CTemperatureMonitor::DisableAlarm().
I know this might seem really minor and simplistic, but I'm often wondering what exactly should be part of the class. Should the class be outputting to stdout? Does it make any difference whether I do one or the other? Am I being to pedantic about this?
Also, as an aside, I know global variable are considered poor practise. I use the temperature enum in both the main and the class. Should I declare it twice, once in main and once in the CTemperatureMonitor class, or once globally? Although this question seems rather specific, it would actually clear a whole lot of other things up for me.
Thanks.
First off, I'd like to point out that there are various size of projects, and that depending on the size (and criticity), the advices will actually be different. So first a rule of thumb:
The size of the "framework" that you put in place (Logger, Option Parser, etc...) should probably not exceed 10% of the total program. After this point, it's just overkill. Unless it's the goal of the exercise!
That being said, we can start have a look at your actual questions.
Also, as an aside, I know global variable are considered poor practice. I use the temperature enum in both the main and the class. Should I declare it twice, once in main and once in the CTemperatureMonitor class, or once globally?
You are actually mistaking variables and types here. temperature is a type (of enum kind).
In general, Types are used as bridges between various parts of the program, and to do so it is important that all those parts share the same definition of the type. Therefore, for types, it would be bad practice to actually declare it twice.
Furthermore, not all globals are evil. Global variables are (shared state), but global constants are fine, and usually play a role similar to types.
I know this might seem really minor and simplistic, but I'm often wondering what exactly should be part of the class. Should the class be outputting to stdout? Does it make any difference whether I do one or the other? Am I being to pedantic about this?
There are two kinds of output:
logging output, which is used to diagnose issues when they are encountered
real output, which is what the program does
Depending on programs, you might have either, both or none.
From a pedantic point of view, you would generally prefer not mix those. For example, you could perfectly send the logging to a file, or stderr when it's serious, and use stdout for the "useful" stuff.
This actually drives the design somewhat, as then you need two sinks: one for each output.
Being that you have a quite simplistic program, the easiest way might be to simply pass two different std::ostream& to your class upon construction. Or, even simpler, just have two generic functions and use the (evil) global variables.
In larger program, you would probably design a Logger class that would have various log levels and provide specific macros to register (automatically) the function name, file name and line number of the log line. You would also probably have a lightweight logging mechanism that would allow you to disable logging DEBUG/DEV level traces in the Release builds.
The single level of abstraction principle would favor doing all I/O in the same method instead of doing some at a high level and some at a low level of abstraction.
In other words, if you believe in that principle, keeping both input and output via cin/cout in the same method instead of showing some and hiding some is a good idea. It tends to give more readable code with less dependencies in each class.
According to the Single responsibility principle, the second option is preferred (any class should have exactly one responsibility, which is monitoring the temperature in your case, not outputting the results,) though you might want to set up another class to handle the temperature monitoring results (e.g. to write the results to a certain log file or something).
It's normal to have some way of logging information about your program.
It's also normal for this way to be, well, global.
Otherwise things just get too complicated when calling a method.
The only thing you should do to improve this is:
Have a logger class (or use an existing one) that can have its output stream set to whatever you choose (including std::out and an empty stream that doesn't print anything).
Ultimately, have a logger than can be hidden behind a #define so that it does not slow down code running in Release mode.
In my opinion in such cases you should not include cout into class, as maybe sometimes later you will need to output to the file or don't output at all. So if the cout is not put to the class you will have opportunity to reuse your class code without any changes.
Neither. Responsibility of main is to start the application with the command line arguments and to give a return value. Everything else should not be there. You might want to take a look at a book like "Object Design, Roles, Responsibilities, and Collaborations"
How can I derive my own stream from a standard stream?
In C# language, there is a Stream class, but C++'s streams are too complex.
I want something like this:
class my_stream : public std::stream
{
// How to derive?
};
void using_a_stream(std::stream* s)
{
*s << "Hello world";
}
void main()
{
std::stream s1;
std::fstream s2("C:\\test.txt");
my_stream s3;
using_a_stream(&s1);
using_a_stream(&s2);
using_a_stream(&s3);
}
Note: The code just a sample and may be invalid C++ program.
Thanks.
I think there are three levels of answer to this question:
Level 1: It is complicated, especially if you are completely new to C++, stop right now. Only if you feel adventurous, continue to level 2.
Level 2: Use some library that makes creating streams easier. I would suggest using Boost.IOStreams library. It makes creating own streams and streambufs much easier. If you are still not satisfied, continue to level 3.
Level 3: You will have to derive from std::streambuf and modify its behaviour to suit your needs. Then you will have to plug your streambuf into own stream.
Could you please describe a little bit more what you own streamclass should do?
Just asking how without what is not the best way to get a constructive answer.
Maybe you should have a look at boost::iostream, as there is a much simpler and safer way to write own iostream classes.
Don't.
iostreams is an awful interface. It also lacks a lot of features and has awful performance.
Are the C formatted I/O functions (printf, sprintf, etc) more popular than IOStream, and if so, why?
What are the bad habits of C programmers starting to write C++?
Should I use printf in my C++ code?
Is it bad practice to use C features in C++?
Partially truncating a stream (fstream or ofstream) in C++
C++ purists may want to look away now. You will hate this.
I have been given an open source windows console app that I am merging with a pre-existing, very old, very large windows app of my own. My old program started life as pure C though recently has been tweaked so that it can compile as C++. My program makes extensive use of a my_printf() function which prints text to a window.
The old console app does its printing C++ style via streams (I have never used this type of printing mechanism before).
When converting the console app to work under my system I could manually edit all the lines that do printing so that they use my_printf() instead. But before I embarked on that I thought I'd just check with StackOverflow to see if I was missing a trick. For example I could imagine somehow letting the C++ prints be done via the stream and then somehow scooping the final text somewhere and then calling my_printf() with the result. Might that be possible?
EDIT: please note my knowledge of C++ is extremely limited and I may need to look some things up in order to understand your answers so please use language that facilitates this.
There's indeed a trivial trick. But C++ impurists will hate the fact that C++ has a pure solution ;)
std::ostream is responsible for formatting, but not printing itself. That's handled by std::streambuf. std::cout combines a std::ostream formatter with a std::streambuf-derived object that writes to stdout.
However, you can change the streambuf backing an ostream with ostream::rdbuf(newbuf). As std::cout is just another ostream, you can replace its streambuf too. In this case, you only need to come up with a streambuf-derived class that writes already-formatted output to my_printf(). That should be quite trivial.
You might find string streams useful. For example:
std::ostringstream os;
os << "Print " << whatever << data;
my_printf( "%s", os.str().c_str() );
In case you were feeling adventurous, you could write your own streambuf instead that used my_printf underneath, and inject it into the stream object that is currently used in output statements (e.g. std::cout). Be warned that this latter approach might not be trivial, however it would result in almost no changes to existing codebase.
Subclass std::ostream and make operator << call my_print_f(). You can use internal stringstream in your stream to retrieve string representation of operator << arguments.
Then you'd just have to do find&replace, replacing cout (or whatever stream you directed your output to in the console app) with an instance of your stream class.
Something along these lines might be helpful:
http://www.codeproject.com/KB/debug/debugout.aspx
Should be obvious where the meat of it is, so you can make it print via your own systems, or what have you. In theory, you'd need only search for references to std::cout and replace them with references to your own object.
Overloading the global operator<< is probably what will solve your problem:
#include <iostream>
#include <cstdio>
static int
my_printf (const char* s)
{
printf ("my_printf: %s\n", s);
}
namespace std {
std::ostream& operator<< (std::ostream& out, const char* s)
{
my_printf (s);
return out;
}
}
int
main ()
{
std::cout << "hello, world"; // => my_printf: hello, world
return 0;
}