在 C 中的 scanf() 格式说明符中使用字符串长度宏

问题描述 投票:0回答:1

是否可以用宏替换数字

9
,以使这行代码具有更多的代码可维护性?

scanf("%9[^\n]s", str);

我尝试阅读文档,但找不到这些操作的确切名称:

  1. "[^\n]s"

  2. "%ns"

我尝试了这些替代方案,但 Clion 将两行中第一次出现的

str
标记为错误:

scanf("%" str(MAX_LENGHT) "%[^\n]s", str);

scanf("%" str(MAX_LENGTH) "[^\n]%*c", str);
c string macros scanf
1个回答
0
投票

您可以使用字符串化运算符

#
来通过宏实现此目的,但这很棘手且令人困惑:
str
必须定义为调用另一个宏
xstr
的宏,后者又用
#x
对其参数进行字符串化.

这是一个简短的例子:

#include <stdio.h>

#define MAX_LENGTH  9

#define xstr(x)  #x
#define str(x)  xstr(x)

int main(void) {
    char buf[MAX_LENGTH + 1];
    if (scanf("%" str(MAX_LENGTH) "[^\n]", buf) == 1) {
        printf("got |%s|\n", buf);
    }
    return 0;
}

如果

str
被定义为
#define str(x) #x
,则调用
str(MAX_LENGTH)
将扩展为
"MAX_LENGTH"
。第二个宏调用在第一次扩展初始宏参数后执行其替换,因此
str(MAX_LENGTH)
调用
xstr(9)
,它扩展为
"9"

但请注意,

MAX_LENGTH
不是目标数组的长度:必须为空终止符添加一个额外的字符,并且宏调用中没有一致性检查:
MAX_LENGTH
buf定义之间的一致性
完全依赖程序员。

© www.soinside.com 2019 - 2024. All rights reserved.