0

I am using the following printf function:

    printf("%-8s%-21s%-17s%-6s\n", "index", "Name", "Effect", "Type");

However, instead of "8", I'd like to use a pre-defined macro:

#define NAME_SIZE 8

When I tried to replace it, the IDE doesn't recognise it and gives the error: Invalid conversion specifier N (the first letter of the macro). I tried putting the macro name in () brackets or putting an interval these but didn't work either. So I wonder: is it even possible to put a macro as a parameter in a printf function and if yes, how? I am sorry for such a strange question but I couldn't find any information.

Kotaka Danski
  • 451
  • 1
  • 4
  • 14
  • Have you tried to compile it? Sometimes the IDEs show false positive errors. –  Mar 15 '21 at 08:58
  • 5
    If you can define as `"8"` then would `printf("%-"NAME_SIZE"s%-21s%-17s%-6s\n", "index", "Name", "Effect", "Type");`do what you want? – Yunnosch Mar 15 '21 at 08:59
  • You can use the `*` in place of the explicit number and pass the value as an `int` argument before the corresponding string: `printf("%-*s%-21s%-17s%-6s\n", (int)(NAME_SIZE), "index", "Name", "Effect", "Type");` – chqrlie Mar 15 '21 at 09:15
  • @Yunnosch I am using the macro for an array size, so it doesn't work exactly how I wanted. Thank you nevertheless. – Kotaka Danski Mar 15 '21 at 09:29
  • @chqrlie That's what I needed! Thank you! – Kotaka Danski Mar 15 '21 at 09:30

3 Answers3

5

Yes you can indeed do this (although in your specific case you can pass the parameter width which is a better method). Indeed some of the standard libraries for C and C++ exploit this (or put another way, ratify this as a legitimate technique), for example with PRId64 for the correct formatting of int64_t:

#include <inttypes.h>
int64_t t = 0;
printf("%" PRId64 "\n", t);

In your case, you need

#define NAME_SIZE "8"

along with

printf("%-"NAME_SIZE"s%-21s%-17s%-6s\n", "index", "Name", "Effect", "Type");
Bathsheba
  • 231,907
  • 34
  • 361
  • 483
3

Assuming that you can define the macro slightly differently:

If you can define as #define NAME_SIZE "8" then printf("%-"NAME_SIZE"s%-21s%-17s%-6s\n", "index", "Name", "Effect", "Type"); would do what I understand to be your goal.

This is because the compiler will concatenate directly adjacent string literals like "a""b" to "ab".

If the macro has to be precisely as shown, you'd have to take a detour via using the # operator in another level of macro.

Yunnosch
  • 26,130
  • 9
  • 42
  • 54
0

You can do something like the following way

#include <stdio.h>

#define SIZE( X )   #X

int main(void) 
{
    printf("%-" SIZE( 8 ) "s%-21s%-17s%-6s\n", "index", "Name", "Effect", "Type");
    printf("%-8s%-21s%-17s%-6s\n", "index", "Name", "Effect", "Type");
    
    return 0;
}

The program output is

index   Name                 Effect           Type  
index   Name                 Effect           Type
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Looks good to me. Then `X` could also be used as an integer constant elsewhere. `#define X 8 printf("pi to %d places: %." SIZE( X ) "f\n", X+1, X, acos(-1));` to print pi at some constant precision. This is more valuable with `scanf()`, than `printf()` though as `printf()` has a _width_ specifier option. – chux - Reinstate Monica Mar 15 '21 at 13:42