putchar() or ...) output with C++-style
std::cout << ... output can be unsafe. If I recall correctly, they can have separate buffering mechanisms, so the output might not appear in the intended order.
printf() is fundamentally type-unsafe. The type expected for an argument is determined by the format string (
"%d" requires an
int or something that promotes to
"%s" requires a
char*, etc.), but passing the wrong type of argument results in undefined behavior, not a diagnosable error. Some compilers, such as gcc, do a reasonably good job of warning about type mismatches, but they can do so only if the format string is a literal or is otherwise known at compile time (which is the most common case) -- and such warnings are not required by the language. If you pass the wrong type of argument, arbitrarily bad things can happen.
C++'s stream I/O, on the other hand, is much more type-safe, since the
<< operator is overloaded for many different types.
std::cout << x doesn't have to specify the type of
x; the compiler will generate the right code for whatever type
On the other hand,
printf's formatting options are IMHO much more convenient. If I want to print a floating-point value with 3 digits after the decimal point, I can use
"%.3f" -- and it has no effect on other arguments, even within the same
printf call. C++'s
setprecision, on the other hand, affects the state of the stream, and can mess up later output if you're not very careful to restore the stream to its previous state. (This is my personal pet peeve; if I'm missing some clean way to avoid it, please comment.)
Both have advantages and disadvantages. The availability of
printf is particularly useful if you happen to have a C background and you're more familiar with it, or if you're importing C source code into a C++ program.
std::cout << ... is more idiomatic for C++, and doesn't require as much care to avoid type mismatches. Both are valid C++ (the C++ standard includes most of the C standard library by reference).
It's probably best to use
std::cout << ... for the sake of other C++ programmers who may work on your code, but you can use either one -- especially in trace code that you're going to throw away.
And of course it's worth spending some time learning how to use debuggers (but that might not be feasible in some environments).