Search code examples
cprintfposixint32

Using printf width specifier with fixed width integer type variable


w is a parameter that specifies width of output, p is number, that should be printed in octal system Both variables should be fixed-width integers (uint32_t) (it's a task for my programming class). I googled, that I can use macros PRIo32 (inttypes.h) to print int32_t in octal, but I couldn't find any macros for width specifier. So when I try:

printf("%*" PRIo32 "\n", w, p);

I get this error in the testing system

error: field width specifier '*' expects argument of type 'int', but argument 2 has type 'int32_t' [-Werror=format=]

Is there any macros, that solves this? Or I should try something else?


Solution

  • Cast the uint32_t width to an int. @Kamil Cuk

    // printf("%*" PRIo32 "\n", w, p);
    printf("%*" PRIo32 "\n", (int) w, p);
    

    If necessary, detect extreme cases

    assert(w <= INT_MAX);
    printf("%*" PRIo32 "\n", (int) w, p);
    

    No assumptions about int range are needed.


    Deeper

    Note that a single print with huge widths runs into trouble due to environmental limits. Widths above 4095 or so may simply not work.

    Environmental limits The number of characters that can be produced by any single conversion shall be at least 4095. C17dr § 7.21.6.1 15

    Code could use the below to handle pathologically large widths - although it is not efficient.

    uint32_t w2 = w;
    while (w2 > 100) {
      w2--;
      putchar(' ');
    }
    printf("%*" PRIo32 "\n", (int) w2, p);