1

I'm attempting to create an sscanf string literal to aid in buffer overrun prevention in C99. The goal is something like:

#define MAX_ARG_LEN   16

char arg[MAX_ARG_LEN] = "";

if (sscanf(arg, "%"(MAX_ARG_LEN-1)"X", &input) > 0)

The obvious "manual" solution is something like:

#define MAX_ARG_LEN   16
#define MAX_ARG_CHARS "15"

char arg[MAX_ARG_LEN] = "";

if (sscanf(arg, "%"MAX_ARG_CHARS"X", &input) > 0)

However, I would prefer something to automatically generate "%15X" given a buffer size of 16. This link is almost works for my application: Convert a preprocessor token to a string but it does not handle the -1.

Suggestions?

1 Answer 1

7

Kernighan and Pike discuss this issue in their (excellent) book 'The Practice of Programming' and concluded that the most reliable and portable way to do this is to use sprintf() to generate the format string.

What you could do is define the macro as the length excluding terminal null, and then use that like this:

#define STR_EVALUATE(x)   #x
#define STRINGIFY(x)      STR_EVALUATE(x)
#define MAX_ARG_LEN 15
char arg[MAX_ARG_LEN+1] = "";

if (sscanf(arg, "%" STRINGIFY(MAX_ARG_LEN) "X", &input) > 0)
    ...

Or you could define MAX_ARG_STRLEN as 15 and MAX_ARG_LEN as MAX_ARG_STRLEN+1 and work accordingly.

Sign up to request clarification or add additional context in comments.

3 Comments

In case anyone is interested, a longish explanation of why STRINGIFY() needs to be done the way Jonathan did it (with a layer of indirection): stackoverflow.com/questions/798221/c-macros-to-create-strings/…
There's also the parallel discussion for token pasting (##) at SO 1489932.
The +1 implementation above is a perfectly good solution - thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.