Skip to content

Latest commit

 

History

History
119 lines (80 loc) · 4.38 KB

File metadata and controls

119 lines (80 loc) · 4.38 KB

std::printf: Formatted Output (C++11)

The printf function is a powerful and versatile tool for producing formatted output. Originating from the C standard library, it is available in C++ via the <cstdio> header. While modern C++ offers alternatives like iostreams (std::cout) and std::format, printf remains prevalent in many codebases due to its efficiency, control, and long history.

What It Is and When to Use It

At its core, printf ("print formatted") sends a formatted string to the standard output (usually the console). It works by taking a "format string" as its first argument, which contains placeholders. These placeholders are then replaced by the subsequent arguments in the function call.

Pro's

  • Performance: printf is often faster than C++ iostreams because it does very little work at compile time and avoids the overhead of constructing and destructing stream objects. Although the performance is overhead is very small.

  • Concise Formatting: For complex formatting (e.g., padding, precision, signs), the syntax is compact and powerful.

  • C Compatibility: It is the standard for formatted output in C, making it essential for projects that need to maintain C compatibility.

  • Wide Availability: It is part of the standard library on virtually every platform that supports C/C++.

Con's

  • Not Type-Safe: The compiler does not check if the types of the arguments match the format specifiers. A mismatch leads to undefined behavior, which can cause crashes, security vulnerabilities, or silent data corruption. This is the single biggest drawback of printf.

  • No Extensibility for User-Defined Types: printf only knows how to print built-in types. It cannot be extended to handle custom classes or structs without manually calling member functions to get printable data.

Basic Usage

The basic syntax of printf involves a format string and a variable number of arguments:

#include <cstdio>
#include <string>

int main() {
    // Basic string and integer
    printf("Hello, %s!\n", "world");
    printf("The answer is %d.\n", 42);

    // Multiple arguments
    const char* user = "Jane";
    int score = 100;
    printf("User: %s, Score: %d\n", user, score);
    return 0;
}
Hello, world!
The answer is 42.
User: Jane, Score: 100

Format Specifiers

The Specifier

printf uses format specifiers that start with a % symbol to indicate how to format each argument. Here are some common format specifiers:

  • %d or %i: Integer
  • %u: Unsigned integer
  • %f: Floating-point number
  • %s: String
  • %c: Character
  • %x or %X: Hexadecimal
  • %o: Octal
  • %p: Pointer
printf("[%.5d]\n", 42);         // Integers: pads with zeros -> "[00042]"
printf("[%.2f]\n", 3.14159);   // Floats: rounds -> "[3.14]"
printf("[%.5s]\n", "Hello, world"); // Strings: truncates -> "[Hello]"

Flags and Width Specifiers (Optional)

You can use flags and width specifiers to control the formatting:

  • Width: printf("%5d", 42); will print 42 (three spaces followed by "42").
  • Precision: printf("%.2f", 3.14159); will print 3.14.
  • Flags:
    • -: Left-justify the value.
    • +: Always display the sign for numerical values.
    • 0: Zero-padding.

Example:

printf("%-10s %05d %+8.2f\n", "Hello", 42, 3.14159);

Output:

Hello      00042    +3.14
printf("[%5d]\n", 42);      // Prints "[   42]" (padded with 3 spaces)
printf("[%-5d]\n", 42);     // Prints "[42   ]" (left-justified)
printf("[%05d]\n", 42);     // Prints "[00042]" (padded with zeros)

Variable Arguments

printf can take a variable number of arguments, but it's not type-safe. The format string must correctly represent the types of the arguments, or undefined behavior will occur.

Return Value

printf returns the number of characters that are printed, or a negative value if an error occurs.

Error Handling

printf lacks strong error handling. If the format string and the provided arguments don't match, the behavior is undefined. This is one of the main criticisms of printf compared to type-safe alternatives like std::format.

Performance

printf is generally fast because it doesn't have the overhead of type checking. However, this comes at the cost of safety.

Compatibility

printf is available in both C and C++, making it a common choice for code that needs to be compatible with both languages.