我有一个程序,它从命令行获取一个格式字符串,该字符串表示多个输出文件的文件名格式。它应该只需要一个可以替换的整数参数来生成真正的输出文件名,我想在进行输入检查时验证这一点。确定格式字符串在 C 中期望的参数数量的好方法是什么?
2 回答
接受的参数数量取决于 C 库的版本(例如,%a
在 C99 中添加了转换说明符)。您可以确定它不大于未转义%
字符的数量(即,删除%
所有序列后剩余的字符%%
数量)加上*
字符数量(可能是宽度说明符)。
不过,您应该考虑安全问题;如果用户提供%n
格式说明符,这可能会导致写入任意内存位置。在其他情况下,提供例如%f
将导致在任意内存内容中输出垃圾值%s
,甚至使用%d
允许用户提供字段宽度的说明符,例如%255d
可能导致缓冲区溢出。考虑不同的格式化方案会更聪明,例如替换令牌(仍然可以是%d
),但不允许用户提供printf
格式字符串。
GNU C 库包含一个parse_printf_format
可以在您的情况下使用的函数。来自glibc 手册,第 12.12.10 节 - Parsing a template string:
您可以使用函数 parse_printf_format 来获取有关给定模板字符串预期的参数的数量和类型的信息。此函数允许为 printf 提供接口的解释器避免传递来自用户程序的无效参数,这可能导致崩溃。
parse_printf_format 返回模板所需的参数总数。如果此数字大于 n,则返回的信息仅描述前 n 个参数。如果您需要有关其他参数的信息,请分配一个更大的数组并再次调用 parse_printf_format。
用例示例:
#include <printf.h>
size_t arguments_count = parse_printf_format ("Your discount: %d%%\n", 0, NULL);
/* arguments_count now holds a value of 1 */