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(),这可能会设置EILSEQerrno)

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的主要内容,如果未能解决你的问题,请参考以下文章

Linux ioctl 返回值由谁解释?

Linux内核错误返回值ERRNO宏列表

sprintf

Java中方法类里面有返回值和没有返回值问题!

Android——关于Activity跳转的返回(无返回值和有返回值)——无返回值

函数的返回值和函数调用