Вопрос

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.

Это было полезно?

Решение

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);

Другие советы

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top