如何在格式字符串中使用define?

时间:2017-11-17 08:19:47

标签: c c-preprocessor format-specifiers

说我有一个字符数组:

#define LEN 10
char arr[LEN + 1];

让我们对它进行一些scanf操作:

scanf("Name: %s", arr);

如果有人输入的名称超过10个字符,这可能会很危险。所以最好用这个:

scanf("Name: %10s", arr);

好吧,如果更改LEN,我会遇到麻烦。我必须通过整个代码来纠正我在10的上下文中使用arr的每一行。所以我想到了这样的事情:

scanf("Name: %LENs", arr);

但这不起作用。预处理器无法解析LEN,因为它在字符串中使用。

如何在格式字符串中使用define?

1 个答案:

答案 0 :(得分:21)

C连接相邻的字符串文字,你可以使用#将预处理器参数字符串化,所以下面应该可以做到这一点:

#define LEN 10

// this converts to string
#define STR_(X) #X

// this makes sure the argument is expanded before converting to string
#define STR(X) STR_(X)

[...]

scanf("Name: %" STR(LEN) "s", arr);

需要使用宏,因为只有#LEN,您最终会将LEN扩展为10,并且只有一个宏将[{1}}应用于其参数,结果将是#(论证不会扩展)。

预处理器/编译器将按以下步骤对其进行转换:

"LEN"

在最后一步中,字符串文字将合并为一个字符串。

另一方面,您的1. scanf("Name: %" STR_(10) "s", arr); 2. scanf("Name: %" "10" "s", arr); 3. scanf("Name: %10s", arr); 格式字符串需要用户输入

scanf()

实际匹配。我怀疑这是你想要的。你可能想要这样的东西:

Name: xyz

还要考虑根本不使用fputs("Name: ", stdout); fflush(stdout); scanf("%" STR(LEN) "s", arr); 。用例如scanf(),这整个预处理器的魔力已经过时了。由于您不应使用fgets()的原因,请参阅我的beginners' guide away from scanf()