Is there an alternative to printf?

Viewed 8796

printf can be accessed if you #include <stdio.h>. I like using printf because of the format specifiers, and it just feels nicer than doing std::cout << "something\n";.

#include <stdio.h>
#include <cstdlib> // to use rand()

int main() {
    int randNum = rand()%10 + 1;
    printf("Hey, we got %d!\n", randNum);
    return 0;
}

vs

#include <iostream>
#include <cstdlib> // to use rand()
using std::cout;

int main() {
    int randNum = rand()%10 + 1;
    cout << "Hey, we got " << randNum << "!\n";
    return 0;
}

But a user in a discord server that I am in said it was bad practice because "printf is unsafe, use std::cout".

A second user said it was bad because it's not type safe (the first user did mention type safety but not in depth).

The second user said,

Typesafety is enforced by the compiler. However by using a variadic function, the compiler cannot tell the type of the arguments at runtime; it can't know them in advance. The function needs some way to tell what type of arguments to expect, and the printf family of C functions did this through the format string specifiers.

So I'm looking for other alternatives.

If there are none I guess I'll just stick to std::cout

3 Answers

The GNU C++ compiler g++ checks printf arguments at compile-time. If you specify -Wall on the command line, it issues a warning if it detects a mismatch. So if you are using this compiler, you can use printf without worrying.

Your compiler may or may not offer a similar service. But hell, use printf anyway, at least in preference to the ridiculous cout mechanism. Or for a type-safe solution, you might consider using the Boost Format library.

Edited to add: This question has a discussion that you might find interesting.

As an alternative on embedded devices you could consider the <1KB Open Source Trice, which allows printf-like comfort also inside interrupts by delegating the printing task to the external log viewer. I developed this tool, because I found nothing better.

As kindly explained by @TonyK, snprintf and sprintf are used to write into a buffer and not to the standard stream. Instead of just answering the specific question, this explains a broader solution.


For a "safer" function, you could look at using snprintf where the size of the object is explicitly specified.

Without specifying the size and using printf, you have to "trust" that the provided char* is a valid C-string with terminating null character, otherwise printf will keep reading the memory.


Generally speaking, if the requirements is to only use C and only have a dependency on the associated C runtime library (glibc on Linux, msvcrt/ucrt on Windows, ...), using only C header and and using a C compiler makes sense.

If using C++ is an option, using std::cout is a natural choice as it will support displaying any object implementing the ostream::operator<<.

Answers on what is the best choice will dependent on what you try to achieve.

Related