C 确定printf参数的数量

C 确定printf参数的数量,c,C,是否有一个标准的C/C++函数,在给定printf格式字符串的情况下,返回它期望的参数数?例如: num_printf_args("%d %s") == 2; num_printf_args("%.1f%%") == 1; num_printf_args("%*d") == 2; 仅计算格式字符串中%的数量将是第一个近似值,在第一个示例中有效,但在第二个和第三个示例中显然不起作用 我知道gcc可以做到这一点,因为在编译时,它会抱怨实际传递给printf的参数数量及其类型与格式字符串不匹配。没有

是否有一个标准的C/C++函数,在给定printf格式字符串的情况下,返回它期望的参数数?例如:

num_printf_args("%d %s") == 2;
num_printf_args("%.1f%%") == 1;
num_printf_args("%*d") == 2;
仅计算格式字符串中%的数量将是第一个近似值,在第一个示例中有效,但在第二个和第三个示例中显然不起作用


我知道gcc可以做到这一点,因为在编译时,它会抱怨实际传递给printf的参数数量及其类型与格式字符串不匹配。

没有标准函数可以做到这一点

然而,它很容易实现

计算未后跟另一个%的%数。每个计数的百分比加1,紧接着是*

计数%个字符的运行时,不允许重叠。因此%%%d的值应该是1而不是0,当然也不是2或3

编辑-在用户694733的评论后添加以下文本

这将足以按照您给出的三个示例的行格式化字符串。然而,正如用户694733在评论中指出的,这并不是全部


一般来说,格式说明符遵循原型%[flags][width][.precision][length]说明符。上述方法是一个起点,适用于没有标志、宽度说明符中可能有*的格式字符串、精度说明符中没有*的格式字符串,并且忽略了长度和说明符字段。对于通用格式字符串,需要考虑所有这些因素,并相应地解析字符串。要做到这一点,需要付出的努力取决于您需要计数的健壮程度——例如,如果需要检测无效的格式字符串,则需要付出更多的努力。

没有标准函数可以做到这一点

然而,它很容易实现

计算未后跟另一个%的%数。每个计数的百分比加1,紧接着是*

计数%个字符的运行时,不允许重叠。因此%%%d的值应该是1而不是0,当然也不是2或3

编辑-在用户694733的评论后添加以下文本

这将足以按照您给出的三个示例的行格式化字符串。然而,正如用户694733在评论中指出的,这并不是全部


一般来说,格式说明符遵循原型%[flags][width][.precision][length]说明符。上述方法是一个起点,适用于没有标志、宽度说明符中可能有*的格式字符串、精度说明符中没有*的格式字符串,并且忽略了长度和说明符字段。对于通用格式字符串,需要考虑所有这些因素,并相应地解析字符串。要做到这一点,需要付出的努力取决于您的计数的健壮程度——例如,如果您需要检测无效的格式字符串,则需要付出更多的努力。

我不确定您为什么需要这样做,但是您的问题可能会在以下问题的公认答案中得到解决:

正如注释中所建议的那样,您可以将printf的调用封装到一个宏中,该宏将首先计算所需参数的数量,然后继续执行您想要执行的任何操作

来自博客帖子的代码:

#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(__VA_ARGS__, 5,4,3,2,1)
#define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,N,...) N

// to verify, run the preprocessor alone (g++ -E):
VA_NUM_ARGS(x,y,z)

我不知道您为什么需要这个,但是您的问题可能会在这个问题的公认答案中得到解决:

正如注释中所建议的那样,您可以将printf的调用封装到一个宏中,该宏将首先计算所需参数的数量,然后继续执行您想要执行的任何操作

来自博客帖子的代码:

#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(__VA_ARGS__, 5,4,3,2,1)
#define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,N,...) N

// to verify, run the preprocessor alone (g++ -E):
VA_NUM_ARGS(x,y,z)

ISO/IEC 9899:1999语言标准中没有此类功能。不完全确定:2011年,但我不这么认为。这是一个由GCC实现的扩展。如果没有关于参数类型的信息,它为什么会有用?它不是语言的一部分,而是一个特定的GCC扩展。请参阅中的格式。按照我的理解,您有固定格式的字符串,printf将从中返回输出的字符数,您有可变函数,可以接受可变数量的参数,但没有printf返回预期的转换数。这并不是说您不能创建一个包装器来解析格式字符串的内容并返回预期的转换次数,如果列表中提供了这些参数,还可以对其进行类型检查。@n.m.如果没有关于参数类型的信息,它为什么会有用呢?计算预期参数的数量实际上是确定参数应该是什么的先决条件。你必须知道它们在哪里,然后才能知道它们是什么,知道它们在哪里意味着知道数字。ISO/IEC 9899:1999语言标准中没有这样的功能。不完全确定:2011年,但我不这么认为。这是一个由GCC实现的扩展。如果没有关于参数类型的信息,它为什么会有用?它不是语言的一部分,而是一个特定的GCC扩展。请参阅中的格式。按照我的理解,您有固定格式的字符串,printf将从中返回输出的字符数,您有可变格式的字符串
函数将接受可变数量的参数,但没有返回预期转换次数的printf。这并不是说您不能创建一个包装器来解析格式字符串的内容并返回预期的转换次数,如果列表中提供了这些参数,还可以对其进行类型检查。@n.m.如果没有关于参数类型的信息,它为什么会有用呢?计算预期参数的数量实际上是确定参数应该是什么的先决条件。你必须先知道它们在哪里,然后才能知道它们是什么,知道它们在哪里意味着知道数字。这并不是那么简单。你还需要考虑双*和旗的情况;例如%+*.*f。实际上,您需要实现完整的格式字符串解析器。@user694733。对于OP给出的例子,我的回答就足够了,但我同意-其他例子不会/我将添加一个关于限制的评论,以及其他需要马上完成的事情。这并不是那么简单。你还需要考虑双*和旗的情况;例如%+*.*f。实际上,您需要实现完整的格式字符串解析器。@user694733。对于OP给出的例子,我的回答就足够了,但我同意-其他例子不会/我将添加关于限制的评论,以及其他需要尽快完成的事情。