开发者

printf vs. std::cout [duplicate]

This question already has answers here: Closed 12 years ago.

Possible Duplicate:

Should I use printf in my C++ code? 开发者_C百科

If I just want to print a string on screen, I can do that using those two ways:

printf("abc");

std::cout << "abc" << std::endl;

The case is, and in the examples shown above, is there an advantage of using printf over std::cout, or, vice versa?


While cout is the proper C++ way, I believe that some people and companies (including Google) continue to use printf in C++ code because it is much easier to do formatted output with printf than with cout.

Here's an interesting example that I found here.

Compare:

printf( "%-20s %-20s %5s\n" , "Name" , "Surname" , "Id" );

and

cout << setw( -20 ) << "Name" << setw( 20 ) << "Surname"  << setw( 5 ) << "Id" << endl;


printf and its associated friends are C functions. They work in C++, but do not have the type safety of C++ std::ostreams. Problems can arise in programs that use printf functions to format output based on user input (or even input from a file). For example:

int main()
{
    char[] a = {'1', '2', '3', '4'}; // a string that isn't 0-terminated
    int i = 50;
    printf("%s", a); // will continue printing characters until a 0 is found in memory
    printf("%s", i); // will attempt to print a string, but this is actually an integer
}

C++ has much stronger type safety (and a std::string class) to help prevent problems like these.


I struggle with this very question myself. printf is in general easier to use for formatted printing, but the iostreams facility in C++ has the big advantage that you can create custom formatters for objects. I end up using both of them in my code as necessary.

The problem with using both and intermixing them is that the output buffers used by printf and cout are not the same, so unless you run unbuffered or explicitly flush output you can end up with corrupted output.

My main objection to C++ is that there is no fast output formatting facility similar to printf, so there is no way to easily control output for integer, hex, and floating point formatting.

Java had this same problem; the language ended up getting printf.

Wikipedia has a good discussion of this issue at http://en.wikipedia.org/wiki/Printf#C.2B.2B_alternatives_to_sprintf_for_numeric_conversion.


Actually for your particular example, you should have asked which is preferable, puts or cout. printf prints formatted text but you are just outputting plain text to the console.

For general use, streams (iostream, of which cout is a part) are more extensible (you can print your own types with them), and are more generic in that you can generate functions to print to any type of stream, not just the console (or redirected output). You can create generic stream behaviour with printf too using fprintf which take a FILE* as a FILE* is often not a real file, but this is more tricky.

Streams are "typesafe" in that you overload with the type you are printing. printf is not typesafe with its use of ellipses so you could get undefined results if you put the wrong parameter types in that do not match the format string, but the compiler will not complain. You may even get a seg-fault / undefined behaviour (but you could with cout if used incorrectly) if you miss a parameter or pass in a bad one (eg a number for %s and it treats it as a pointer anyway).

printf does have some advantages though: you can template a format string then reuse that format string for different data, even if that data is not in a struct, and using formatting manipulations for one variable does not "stick" that format for further use because you specify the format for each variable. printf is also known to be threadsafe whereas cout actually is not.

boost has combined the advantages of each with their boost::format library.


The printf has been borrowed from C and has some limitations. The most common mentioned limitation of printf is type safety, as it relies on the programmer to correctly match the format string with the arguments. The second limitation that comes again from the varargs environment is that you cannot extend the behavior with user defined types. The printf knows how to print a set of types, and that's all that you will get out of it. Still, it for the few things that it can be used for, it is faster and simpler to format strings with printf than with c++ streams.

While most modern compilers, are able to address the type safety limitation and at least provide warnings (the compiler can parse the format string and check the arguments provided in the call), the second limitation cannot be overcome. Even in the first case, there are things that the compiler cannot really help with, as checking for null termination --but then again, the same problem goes with std::cout if you use it to print the same array.

On the other end, streams (including std::cout) can be extended to handle user defined types by means of overloaded std::ostream& operator<<( std::ostream&, type const & ) for any given user defined type type. They are type safe by themselves --if you pass in a type that has no overloaded operator<< the compiler will complain. They are, on the other hand, more cumbersome to produce formatted output.

So what should you use? In general I prefer using streams, as overloading operator<< for my own types is simple and they can be used uniformly with all types.


Those two examples do different things. The latter will add a newline character and flush output (result of std::endl). std::cout is also slower. Other than that, printf and std::cout achieve the same thing and you can choose whichever you prefer. As a matter of preference, I'd use std::cout in C++ code. It's more readable and safer.

See this article if you need to format output using std::cout.


In general, you should prefer cout because it's much type-safer and more generic. printf isn't type-safe, nor is it generic at all. The only reason you might favour printf is speed- from memory, printf is many times faster than cout.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜