格式化字符串的预处理器和替换

时间:2015-07-15 15:25:02

标签: c string c-preprocessor scanf format-string

如果我把:

#define SIZE 10

之后:

scanf("%SIZEs", s);

我遇到运行时错误。预编译器应该在编译之前用SIZE替换10,所以这应该等于(在我看来)写

scanf("%10s", s);

那么,错误在哪里?

2 个答案:

答案 0 :(得分:3)

无法用宏替换字符串文字的内容 例如,它执行以下操作:

#include <stdio.h>

#define S_(x) #x
#define S(x) S_(x)

#define SIZE 10

int main(void){
    char s[SIZE + 1];
    scanf("%" S(SIZE) "s", s);
    puts(s);
    return 0;
}

答案 1 :(得分:2)

在您的代码中,问题出在

  scanf("%SIZEs", s);

格式字符串(字符串文字)的引号" "之间的任何内容都不会通过MACRO替换取代。

因此,您的scanf()保持与您编写的相同,在预处理之后,%S(或,%SIZEs,整体而言)是一个无效的格式说明符,您进入undefined behaviour因此得到了错误。

您可以尝试使用

作为解决方法
 scanf("%"SIZE"s", s);

这样,SIZE将在引号之外,并将在预处理阶段考虑替换。