Home > other >  making format specifier by parsing strings with preprocessor
making format specifier by parsing strings with preprocessor

Time:12-06

Is it possible to make a variable format specifier this way?

#define TOST(i) #i   //to string

printf("str: %" TOST(5) "s \n", "abcdefgh");

when it compiles, it ignores the number. if not this way, still, i would like to know how to make a variable format specifier.

CodePudding user response:

Yes. Your code compiles correctly, producing a format string of "str: %5s \n".

However, note that the expected behavior of printf is that it will print the entire string even if the string exceeds the width you specify in the format string.

CodePudding user response:

The %s specifier has two fields, width.precision.
Width will print at least the indicated characters %5s. Positive widths are right justified. Negative widths are left justified. If there more characters, the output is expanded as needed.
Precision will print no more than the indicated characters %.5s.
.5s would print no more than 5 characters in a field 10 characters wide.

#define TOST(i) #i can be used to insert a integer constant into a string.

A pair of #define's can be used to stringify defined constants.

printf will allow an asterisk to insert an integer value into the format string.

#include <stdio.h>

#define TOST(i) #i   //to string

#define WIDTH 15
#define PRECISION 5
//stringify
#define SFS(x) #x
#define FS(x) SFS(x)

int main ( void) {
    printf("str TOST(15):  [%" TOST(15) "s]\n", "abcdefgh");
    printf("str -TOST(15): [%-" TOST(15) "s]\n", "abcdefgh");
    printf("str .TOST(5):  [%." TOST(5) "s]\n", "abcdefgh");

    printf("str FS(WIDTH):      [%" FS(WIDTH) "s]\n", "abcdefgh");
    printf("str -FS(WIDTH):     [%-" FS(WIDTH) "s]\n", "abcdefgh");
    printf("str .FS(PRECISION): [%." FS(PRECISION) "s]\n", "abcdefgh");

    int limit = 15;
    printf("str int limit = 15:  [%*s]\n", limit, "abcdefgh");
    printf("str -int limit = 15: [%-*s]\n", limit, "abcdefgh");
    limit = 5;
    printf("str .int limit = 5:  [%.*s]\n", limit, "abcdefgh");
}

CodePudding user response:

The width of a field is the minimum field width, not maximum. The string is longer than 5, so minimum is ignored.

While it is possible with preprocessor, why use it. Just use:

printf("str: %.*s \n", 5, "abcdefgh");
  • Related