I generally use cout
and cerr
to write text to the console. However sometimes I find it easier to use the good old printf
statement. I use it when I need to format the output.
One example of where I would use this is:
// Lets assume that I'm printing coordinates...
printf("(%d,%d)\n", x, y);
// To do the same thing as above using cout....
cout << "(" << x << "," << y << ")" << endl;
I know I can format output using cout
but I already know how to use the printf
. Is there any reason I shouldn't use the printf
statement?
If you ever hope to i18n your program, stay away from iostreams. The problem is that it can be impossible to properly localize your strings if the sentence is composed of multiple fragments as is done with iostream.
Besides the issue of message fragments, you also have an issue of ordering. Consider a report that prints a student's name and their grade point average:
When you translate that to another language, the other language's grammar may need you to show the GPA before the name. AFAIK, iostreams has not way to reorder the interpolated values.
If you want the best of both worlds (type safety and being able to i18n), use Boost.Format.
C++ streams are overrated, after all they're in fact just classes with an overloaded operator
<<
.I've read many times that streams are the C++ way as printf is the C way, but they are both library features available in C++, so you should use what suits best.
I mostly prefer printf, but I've also used streams, which provide cleaner code and prevent you from having to match % placeholders to arguments.
On the whole I agree (hate the << syntax especially if you need complex formatting)
But I should point out the safety aspects.
Probably won't be noticed by the compiler but could crash your app.
Streams are the canonical way. Try making this code work with
printf
:Good luck.
What I mean is, you can make operators to allow your types to be outputted to
ostream
's, and without hassle use it just like any other type.printf
doesn't fit the the generality of C++, or more specifically templates.There's more than usability. There's also consistency. In all my projects, I have cout (and
cerr
andclog
) tee'd to also output to a file. If you useprintf
, you skip all of that. Additionally, consistency itself is a good thing; mixingcout
andprintf
, while perfectly valid, is ugly.If you have an object, and you want to make it output-able, the cleanest way to do this is overload
operator<<
for that class. How are you going to useprintf
then? You're going to end up with code jumbled withcout
's andprintf
's.If you really want formatting, use Boost.Format while maintaining the stream interface. Consistency and formatting.
You can get the best of both worlds with the fmt library which combines safety and extensibility of iostreams with usability and performance of
(s)printf
. Example:The library supports Python-like and printf format string syntax.
Disclaimer: I'm the author of the fmt library.
Use boost::format. You get type safety, std::string support, printf like interface, ability to use cout, and lots of other good stuff. You won't go back.