What is %*d in c?

Learn what is %*d in c? with practical examples, diagrams, and best practices. Covers c, format-specifiers development techniques with visual explanations.

Understanding the %*d Format Specifier in C

Hero image for What is %*d in c?

Explore the %*d format specifier in C's scanf and printf functions, learning how it controls field width dynamically for input and output operations.

The C programming language offers a rich set of format specifiers for its input/output functions like printf and scanf. While many are straightforward, some, like %*d, can be a source of confusion due to their dual behavior depending on the context. This article will demystify %*d, explaining its role in both printf (for dynamic field width) and scanf (for skipping input), providing clear examples and use cases.

The %*d Specifier in printf: Dynamic Field Width

When used with printf, the * in %*d acts as a placeholder for the field width. Instead of hardcoding a number (e.g., %5d for a width of 5), you can pass the width as an argument before the actual integer value. This allows for dynamic formatting, where the width can be determined at runtime, making your output more flexible and adaptable.

#include <stdio.h>

int main() {
    int value = 123;
    int width1 = 5;
    int width2 = 10;

    printf("Using %%5d:   |%5d|\n", value);
    printf("Using %%*d (width %d): |%*d|\n", width1, value);
    printf("Using %%*d (width %d): |%*d|\n", width2, value);

    return 0;
}

Example of %*d for dynamic field width in printf.

In the printf context, the * tells the function to expect an int argument before the argument to be formatted by d. This int argument specifies the minimum field width. If the formatted value is shorter than the specified width, it will be padded with spaces (by default, on the left). If it's longer, the full value will be printed, ignoring the width specification.

flowchart TD
    A[Start printf call] --> B{Format String Contains %*d?}
    B -- Yes --> C[Expect integer 'width' argument]
    C --> D[Expect integer 'value' argument]
    D --> E{Is value length < width?}
    E -- Yes --> F[Pad value with spaces to 'width']
    E -- No --> G[Print value as is]
    F --> H[Output formatted string]
    G --> H
    B -- No --> I[Process other specifiers]
    I --> H

Flowchart illustrating printf's handling of %*d.

The %*d Specifier in scanf: Suppressing Input

The behavior of %*d changes significantly when used with scanf. Here, the * indicates that the corresponding input item should be read from the input stream but not stored in any variable. It effectively tells scanf to skip that particular data field. This is useful when you need to parse a specific format but only care about certain parts of the input.

#include <stdio.h>

int main() {
    int day, year;
    // Input format: DD-MM-YYYY (e.g., 25-12-2023)
    printf("Enter date (DD-MM-YYYY): ");
    // Read day, skip month, read year
    scanf("%d-%*d-%d", &day, &year);

    printf("You entered: Day = %d, Year = %d\n", day, year);

    return 0;
}

Example of %*d for suppressing input in scanf.

In this scanf example, %*d is used to read the month value but discard it immediately, preventing it from being assigned to any variable. This is particularly handy for skipping delimiters or irrelevant data fields in a structured input string without needing to declare a dummy variable.

Key Differences and Use Cases

The fundamental difference lies in the direction of data flow and the purpose of the * modifier:

  • printf (%*d): Output formatting. The * signifies that the field width is provided as an argument to printf, allowing dynamic control over how an integer is displayed.
  • scanf (%*d): Input parsing. The * signifies that the input value should be read and discarded, preventing it from being stored in a variable. This is useful for skipping parts of the input stream.
graph TD
    A[Context] --> B{printf}
    A --> C{scanf}

    B --> B1[Purpose: Dynamic Output Formatting]
    B1 --> B2[*: Placeholder for 'width' argument]
    B2 --> B3[Example: printf("%*d", width, value)]

    C --> C1[Purpose: Suppress Input]
    C1 --> C2[*: Read but Discard Input]
    C2 --> C3[Example: scanf("%*d", &value)]

Comparison of %*d behavior in printf vs. scanf.