如果将负数或0作为第二个参数传递给snprintf()
,它是否会在提供的缓冲区位置写入。想知道这不会导致任何意外行为。
int snprintf(char *str, size_t size, const char *format, ...);
答案 0 :(得分:9)
引用C11
,chpater§7.21.6.5, snprintf()
函数
int snprintf(char * restrict s, size_t n,const char * restrict format, ...);
[...]如果
n
为零,则不写任何内容, 并且s
可能是空指针。
因此,如果您传递0,则不会写任何内容。
如果您传递-
ve值,则可能会产生问题,因为第二个参数的类型为size_t
unsigned
。因此,签名值将被视为unsigned
,产生不需要的大小。这可能会导致问题(内存溢出),因为大小可能超过提供的缓冲区可以处理的内容,这会调用undefined behavior。
。然而,只要缓冲区足够大以便能够保存提供的数据,所提供的数据就会被写入缓冲区。
来自§7.19,<stddef.h>
size_t
这是sizeof运算符的结果的无符号整数类型;
答案 1 :(得分:4)
将0
传递给snprintf
没有字符将被插入dest
缓冲区。
将一个负数传递给一个size_t
参数,即unsigned
,您传递的数字非常大size
。
尝试
printf("%zu\n%zu\n", (size_t)(-1), SIZE_MAX);
因此,使用负大小参数,您可以写出比真实目标缓冲区大小更多的字节,换句话说就是未定义行为/缓冲区溢出。
答案 2 :(得分:0)
虽然现有答案是正确的,当说给定大小为0时不会将字节写入目标缓冲区时,它们无法通知您,在这种情况下,返回值snprintf
将是格式参数大小的总和。有时可能会很方便地意识到这一点:)
从手册:
返回值
成功返回后,这些函数返回数字 打印的字符数(不包括用于结束输出到的空字节) 字符串)。
函数snprintf()和vsnprintf()的写操作不超过size 字节(包括终止的空字节('\ 0'))。 如果输出 由于此限制而被截断,则返回值为 字符数(不包括终止的空字节) 如果有足够的空间已被写入最终字符串 。因此,返回值size或更大意味着 输出被截断。 (另请参见以下“注释”下的内容。)
如果遇到输出错误,则返回负值。