Question

It may be the case that we start with an initial type that is heavily used in I/O calls and wish to change the type later. For instance, say we have:

typedef unsigned short int board_idx;
//...
board_idx k_in;
scanf("%10hu", &k_in);

If we later change the type of board_idx, it would be arduous to go back and change all such format specifiers to match this later.

I first guessed a good approach would be to define an associated string literal for the format specifier (preferably right next to the type definition of board_idx), and then insert this in to all relevant places in format specifiers. However, this also seems somewhat arduous (using e.g. strcat), so I wonder what others would do in this situation?

Building on the approach at How to replace a piece of const char* with another string in C? suggests that we might be able to do that if we encapsulate the string replacing code in a function that can be applied to format specifiers with unique identifiers that correspond to the respective type. In the above scanf example, this could be:

"%10hu" // should be initially "%board_idx", which can then be replaced

A disadvantage of this method is runtime cost, so I now think a preprocessor solution may be best as long as all the strings the format specifiers are embedded in are known at compile time, e.g:

// Untested and probably won't work ... I'll call it pseudocode:
#define STR(x) #x
#define STRINGIFY(x) STR(x) 
//
#define BOARD_IDX_FMT = %10hu
// "my input is %10hu" becomes:
#define FMTSPEC STRINGIFY(my input is ) #BOARD_IDX_FMT 
printf(FMTSPEC);

But this too would be very complex for strings with many format specifiers.

Était-ce utile?

La solution

However, this also seems somewhat arduous (using e.g. strcat)

In C, adjacent string literals are automatically concatenated at compile time

"asd" "qwe"  --> "asdqwe"

so something along these lines should work

#define FMT "%d"
printf("Hello " FMT "!\n", 17);

Autres conseils

Maybe you can simply cast the value instead of touching format and use:

printf("Hello %d \n", (int)k_in);

to print and

int n;
scanf("%10u", &n);
k_in = (board_idx) n;

to read your k_in.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top