|Prefer iostreams for I/O|
Reason: iostreams are safe, flexible, and extensible.
Discussion: iostreams vs. the printf() family It is often (and often correctly) pointed out that the printf() family has two advantages compared to iostreams: flexibility of formatting and performance. This has to be weighed against iostreams advantages of extensibility to handle user-defined types, resilient against security violations, implicit memory management, and locale handling. If you need I/O performance, you can almost always do better than printf().
gets(), scanf() using %s, and printf() using %s are security hazards (vulnerable to buffer overflow and generally error-prone). C11 defines some “optional extensions” that do extra checking of their arguments. If present in your C library, gets_s(), scanf_s(), and printf_s() may be safer alternatives, but they are still not type safe.
|Avoid using varargs in your functions' signatures. Avoid calling functions with varargs in their own signatures, including legacy functions and standard C library functions such as sprintf. |
Admittedly, calls to sprintf can often look more compact and easier to read than equivalent calls using stringstream formatting and operator<< = just like it's also admittedly easier to hop into a car without pesky safety belts and bumpers. The risks are just not worth it. printf-related vulnerabilities continue to be a serious security problem at the time of this writing, and an entire subindustry of tools exists to help find such type errors.
Prefer to use type-safe libraries that support variable arguments using other means. For example, the [Boost] format library uses advanced C++ features to combine safety with speed and convenience.