sscanf(input_str, \"%5s\", buf); //reads at max 5 characters from input_str to buf
But I need to use something like %MACRO_SIZEs instead of %5s
if your MACRO_SIZE is const at compile time, you can try this:
#define MACRO_SIZE "5"
snprintf(fmt_str, 100, "%" MACRO_SIZE "s", buf);
Like Stefan said, but for sscanf()
to more properly answer the question, and with a bit more macro trickery:
#define MACRO_SIZE 5
#define FORMAT(S) "%" #S "s"
#define RESOLVE(S) FORMAT(S)
char buf[MACRO_SIZE + 1];
sscanf(input_str, RESOLVE(MACRO_SIZE), buf);
This uses C's automatic joining together of adjacent string literals, to form the required formatting string at compile-time. This only works if MACRO_SIZE
is a preprocessor macro, not if it's a normal runtime variable.
The extra macro call through RESOLVE()
is needed since otherwise the argument would not be resolved to its #define
d value, and we'd end up with a formatting string of "%MACRO_SIZEs"
, which is not what we want.
The "correct" solution is what you call the trivial one. All these clever macros(I'd use m4 myself) are just going to make your code less manageable then if you just left it as a constant.
The problem you have here is strings are not a first class data structure in C. They are an array of bytes. Therefor you have to build the array you want to get the meaning you want, and you build that array with sprintf. It's not pretty, but it's correct.
If you're having performance issues and you've tracked it down to here then yes, eliminate the function calls. But unless the value for MACRO_SIZE is repeated a hundred times or spread out over multiple files I'd just change the literal. A macro is just faking having more flexibility, using sprintf actually gives you flexibility.