说我有一个字符数组:
#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?
答案 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()
。