2010-04-29 25 views
2

我試圖創建一個sscanf字符串文字來幫助C99中的緩衝區溢出防護。我們的目標是一樣的東西:使用C預處理器爲scanf構造一個字符串文字?

#define MAX_ARG_LEN 16 

char arg[MAX_ARG_LEN] = ""; 

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

明顯的「手冊」的解決辦法是這樣的:

#define MAX_ARG_LEN 16 
#define MAX_ARG_CHARS "15" 

char arg[MAX_ARG_LEN] = ""; 

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

不過,我喜歡的東西自動生成「%15X」給予16的緩衝區大小。這個鏈接是差不多適用於我的申請:Convert a preprocessor token to a string但它不處理-1。

對此提出建議?

回答

6

Kernighan和Pike在他們的(優秀)書籍'The Practice of Programming'中討論了這個問題,並得出結論認爲最可靠和便攜的方法是使用sprintf()來生成格式字符串。

你可以做的是定義宏的長度不包括終端空,然後使用這樣的:

#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) 
    ... 

或者你可以定義MAX_ARG_STRLEN爲15和MAX_ARG_LEN爲MAX_ARG_STRLEN + 1和相應的工作。

+0

如果有人感興趣,請按照喬納森的方式(通過間接層)完成對STRINGIFY()的原因的長篇解釋:http://stackoverflow.com/questions/798221/c- macros-to-create-strings/798311#798311 – 2010-04-29 19:20:43

+0

還有在[SO 1489932](http://stackoverflow.com/questions/1489932/c-preprocessor-and-級聯/)。 – 2010-04-29 19:32:49

+0

上面的+1實現是一個非常好的解決方案 - 謝謝! – Brett 2010-04-29 20:40:33