sprintf() 负返回值和errno
Posted
技术标签:
【中文标题】sprintf() 负返回值和errno【英文标题】:sprintf() negative return value and errno 【发布时间】:2013-01-24 13:07:15 【问题描述】:根据http://linux.die.net/man/3/sprintf和http://www.cplusplus.com/reference/cstdio/sprintf/sprintf()
和family返回成功写入的字符数。失败时,返回一个负值。我假设如果格式字符串格式错误可能会发生错误,因此负返回值可能表示malloc()
错误以外的其他内容。 errno
是否设置为指示错误是什么?
【问题讨论】:
【参考方案1】:C++遵从C,C在sprintf()
及其家族的描述中并没有要求或提及errno
(虽然对于某些格式说明符,这些函数被定义为调用mbrtowc()
,这可能会设置EILSEQ
在errno
)
POSIX 要求设置 errno:
如果遇到输出错误,这些函数应返回负值并设置
errno
以指示错误。
明确提及 EILSEQ、EINVAL、EBADF、ENOMEM、EOVERFLOW:http://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html
【讨论】:
当 C/C++ 不需要行为(例如,在sprintf()
失败后设置 errno
)但 POSIX 需要时,这意味着什么?我不清楚 POSIX 在哪里适合 - 如果我编写了名为 sprintf()
的 C 代码,我想我正在调用一个 libc 函数......但是什么决定了我是否得到了 POSIX 所需的行为?
@StoneThrow 您正在使用的操作系统决定了这一点。如果是 Unix(包括 MacOS 和 Linux),则适用 POSIX。如果是 Windows,则取决于其 libc 作者的心血来潮。【参考方案2】:
当我有这样的问题时,我总是喜欢“试试看”的方法。
char buffer[50];
int n, localerr = 0;
n = sprintf(buffer, "%s", "hello");
localerr = errno; // ensure printf doesn't mess with the result
printf("%d chars\nerrno: %d\nstrerror:%s\n", n, localerr, strerror(localerr));
> 5 chars
errno: 0
strerror: Success
n = sprintf(buffer, NULL, NULL);
localerr = errno;
printf("%d chars\nerrno: %d\nstrerror:%s\n", n, localerr, strerror(localerr));
> -1 chars
errno: 22
strerror: Invalid argument
在 linux 上使用 gcc 编译时似乎已设置。所以这是很好的数据,在errno
的man page 中确实提到printf()
(与sprintf()
相同的家族)可能会更改errno
(在底部的示例中)。
【讨论】:
+1 作为证明,但 Cubbi 的回答找到了更具体的文档。 请注意,“试用”方法依赖于实现符合标准并且标准不允许不同行为的空间。有时这种方法会误导你……以上是关于sprintf() 负返回值和errno的主要内容,如果未能解决你的问题,请参考以下文章