模糊性始于C标准本身。C99和C11的snprintf
功能描述相同。这是C99的描述:
7.19.6.5snprintf
函数
简介
1 #include <stdio.h>
int snprintf(char * restrict s, size_t n, const char * restrict format, ...);
说明
2该snprintf
函数等效于fprintf
,除了将输出写入数组(由arguments指定s
)而不是写入流。如果n
为零,则不写入任何内容,并且s
可以为空指针。否则,n-1
将丢弃st以外的输出字符,而不是将其写入数组,并且将空字符写入实际写入数组的字符的末尾。如果在重叠的对象之间进行复制,则行为是不确定的。
返回值
3该snprintf
函数返回将要写入的字符数n
足够大,不计入终止空字符,如果发生编码错误,则不计负值。因此,当且仅当返回值是非负且小于时,才以零结尾的输出被完全写入n
。
一方面句子
否则,将丢弃st以外的输出字符,n-1
而不是将其写入数组,并且在实际写入数组的字符的末尾写入一个空字符
表示
如果(s
指向一个3个字符长的数组的点,和)n
为3,则将写入2个字符,并且丢弃第二个字符之外的字符;然后将空字符写在这2个字符之后(空字符将是写入的第三个字符)。
我相信这可以回答原始问题。
解答:
如果在重叠的对象之间进行复制,则行为是不确定的。
如果n
为0,则不向输出写入任何内容,
否则,如果未遇到编码错误,则输出始终为空终止(无论输出是否适合输出数组;否则,将丢弃某些字符,以使输出数组永远不会溢出),
否则(如果遇到编码错误)输出可以保持为非null终止。
另一方面
,最后一句话
因此,当且仅当返回值是非负且小于 n
给出模棱两可(或者我的英文不够好)。我可以解释这句话中的至少两种方式:
1.输出是空值终止当且仅当返回值为非负和小于n
(这意味着如果返回值不小于n
,即,输出(包括终止null字符)不适合数组,则输出不是null终止)。
2.当且仅当返回值是非负且小于时,输出才完整(不丢弃任何字符)。n
我认为以上解释1与答案相矛盾,引起误解和冗长的讨论。这就是为什么描述snprintf
函数的最后一句话需要更改以消除任何歧义的原因(这为编写C语言标准的建议书提供了基础)。
我相信可以使用http://en.cppreference.com/w/c/io/fprintf(请参阅参考资料4)
)中的模棱两可的示例,感谢@“ Martin Ba”的链接。
另请参见问题“ snprintf:是否有任何C标准提案/计划来更改此功能的描述? ”。