【发布时间】:2012-02-23 21:43:24
【问题描述】:
vsnprintf() 可以返回一个大于 1 的负值吗?如果有,在什么情况下会这样做?
我尝试使用 %ls 作为 char 数组的格式说明符,并尝试复制比分配的数组更大的内容。在这两种情况下,我都得到 -1 作为返回值。
【问题讨论】:
标签: c c-libraries
vsnprintf() 可以返回一个大于 1 的负值吗?如果有,在什么情况下会这样做?
我尝试使用 %ls 作为 char 数组的格式说明符,并尝试复制比分配的数组更大的内容。在这两种情况下,我都得到 -1 作为返回值。
【问题讨论】:
标签: c c-libraries
是的,它可以,就像“它被允许”一样。具体情况取决于您的平台,并且没有以任何方式指定或监管。与返回值有关的唯一可移植的事情是检查它是否有 < 0 以查看是否有错误。
来自标准(7.21.6.12(3),vsnprintf):
以空结尾的输出已被完全写入当且仅当返回值为非负数且小于
n。
任何给定的平台当然可以对返回值做出额外的保证;请查阅您的文档。
【讨论】:
vsnprintf() 返回不同负数的可能性如此感兴趣?仅检查小于零的返回值是可移植的,我不确定通过查找特定的负数会获得什么。注意:缓冲区太小不会返回“错误”,它会返回大于或等于缓冲区大小的非负数(表示输出被截断)。
C99 标准说:
§7.19.6.12
vsnprintf函数#include <stdarg.h> #include <stdio.h> int vsprintf(char *restrict s, size_t n, const char *restrict format, va_list arg);说明
¶2
vsnprintf函数等价于snprintf,带有变量参数列表 替换为arg,它应该由va_start宏初始化(和 可能是后续的va_arg电话)。vsnprintf函数不会调用va_end宏。245) 如果复制发生在重叠的对象之间,则行为是 未定义。返回
¶3
vsnprintf函数返回将被写入的字符数n是否足够大,不包括终止空字符或负数 发生编码错误时的值。因此,空终止输出已 当且仅当返回值为非负且小于n时才完全写入。245) 作为函数
vfprintf、vfscanf、vprintf、vscanf、vsnprintf、vsprintf和vsscanf调用va_arg宏,返回后arg的值是不确定的。
而且,由于它是根据snprintf() 定义的,所以这是该部分:
§7.19.6.5
snprintf函数#include <stdio.h> int snprintf(char *restrict s, size_t n, const char *restrict format, ...);说明
¶2
snprintf函数等价于fprintf,只是输出被写入 一个数组(由参数s指定)而不是流。如果n为零,则不写入任何内容,s可能是一个空指针。否则,n-1st 之外的输出字符是 丢弃而不是写入数组,最后写入一个空字符 实际写入数组的字符数。如果复制发生在对象之间 重叠,行为未定义。返回
¶3
snprintf函数返回将被写入的字符数n是否足够大,不包括终止的空字符或负数 发生编码错误时的值。因此,空终止输出已 当且仅当返回值为非负且小于n时才完全写入。
它并没有说它会在错误时返回-1;只是任何负值。所以是的,允许在错误上给出一个幅度大于 1 的负值。
请注意,Microsoft 针对 Visual Studio 2015 的 vsnprintf 规范说:
vsnprintf返回写入的字符数,不包括终止的空字符。返回值 -1 表示发生了编码错误。如果由 count 指定的缓冲区大小不足以包含由 format 和 argptr 指定的输出,则 vsnprintf 的返回值是在 count 足够大的情况下将写入的字符数。如果返回值大于 count - 1,则输出已被截断。
_vsnprintf和_vsnwprintf如果要写入的字符数小于或等于 count,则返回写入的字符数;如果要写入的字符数大于 count,则这些函数返回 -1,表示输出已被截断。所有函数的返回值都不包括终止的空值,如果写入的话。
请注意,情况并非总是如此:
从 Visual Studio 2015 和 Windows 10 中的 UCRT 开始,
vsnprintf不再与_vsnprintf相同。vsnprintf函数符合C99标准;保留_vnsprintf是为了向后兼容。
为了比较,Visual Studio 2013 documentation 说:
vsnprintf、_vsnprintf和_vsnwprintf如果要写入的字符数小于等于count,则返回写入的字符数;如果要写入的字符数大于 count,则这些函数返回 -1,表示输出已被截断。返回值不包括终止的空值,如果写了一个。
snprintf() 的可比较页面是:
【讨论】: