vsnprintf可以返回幅度大于1的负值吗?

时间:2012-02-01 06:52:11

标签: c c-libraries

vsnprintf()可以返回幅度大于1的负值吗?如果是这样,它在什么情况下会这样做?

我尝试使用%ls作为char数组的格式说明符,并尝试复制大于分配的数组。在这两种情况下,我都得到-1作为返回值。

2 个答案:

答案 0 :(得分:3)

是的,它可以,如“允许”。这种情况取决于您的平台,并未以任何方式指定或管制。返回值唯一可移植的方法是检查< 0以查看是否有错误。

从标准(7.21.6.12(3),vsnprintf):

  

当且仅当返回值为非负且小于n时,以null结尾输出已完全写入

任何给定的平台当然可以对返回值做出额外的保证;请查阅您的文档。

答案 1 :(得分:3)

C99标准说:

  

§7.19.6.12vsnprintf函数

#include <stdarg.h>
#include <stdio.h>
int vsprintf(char *restrict s, size_t n, const char *restrict format, va_list arg);
     

描述

     

¶2vsnprintf函数等效于snprintf,带有变量参数列表   由arg替换,va_start已由va_arg宏初始化(和   可能是后续vsnprintf次来电。 va_end函数不会调用   vsnprintf宏。 245)如果在重叠的对象之间进行复制,则行为是   未定义。

     

返回

     

¶3n函数返回已写入的字符数   已n足够大,不计算终止空字符,或负数   如果发生编码错误,则为value。因此,空终止输出已经   当且仅当返回的值是非负且小于vfprintf时才完全写入。

     

245)作为函数vfscanfvprintfvscanfvsnprintfvsprintfvsscanf ,和   va_arg调用arg宏,返回后snprintf()的值不确定。

并且,因为它是根据snprintf定义的,所以这部分是:

  

§7.19.6.5#include <stdio.h> int snprintf(char *restrict s, size_t n, const char *restrict format, ...); 函数

snprintf
     

描述

     

¶2fprintf函数等同于s,但输出被写入   数组(由参数n指定)而不是流。如果s为零,则不写任何内容,   并且n可以是空指针。否则,输出超出snprintf - 1st的字符   丢弃而不是写入数组,并在末尾写入空字符   实际写入数组的字符。如果在对象之间进行复制   重叠,行为未定义。

     

返回

     

¶3n函数返回已写入的字符数   已n足够大,不计算终止空字符,或负数   如果发生编码错误,则为value。因此,空终止输出已经   当且仅当返回的值是非负且小于-1时才完全写入。


它没有说它会在错误上返回vsnprintf;任何负面价值。所以是的,允许在错误上给出幅度大于1的负值。


Microsoft的版本

请注意,Microsoft针对Visual Studio 2015的vsnprintf规范说:

  

_vsnprintf返回写入的字符数,不包括终止空字符。返回值-1表示发生了编码错误。如果count指定的缓冲区大小不足以包含format和argptr指定的输出,则vsnprintf的返回值是count(如果count足够大)将写入的字符数。如果返回值大于count-1,则输出已被截断。

     

如果要写入的字符数小于或等于count,_vsnwprintfvsnprintf都会返回写入的字符数;如果要写入的字符数大于count,则这些函数返回-1表示输出已被截断。如果写入一个函数,则所有函数的返回值都不包括终止null。

请注意,并非总是如此:

  

从Visual Studio 2015和Windows 10中的UCRT开始,_vsnprintf不再与vsnprintf相同。 _vnsprintf功能符合C99标准;保留vsnprintf是为了向后兼容。

为了进行比较,Visual Studio 2013 documentation说:

  如果要写入的字符数小于或等于count,则

_vsnprintf_vsnwprintfsnprintf()将返回写入的字符数;如果要写入的字符数大于count,则这些函数返回-1表示输出已被截断。如果写入了返回值,则返回值不包括终止空值。

{{1}}的可比较页面是: