sprintf()的负返回值和errno

14
2个回答

11

C++ 借鉴了 C 语言,但是在描述 sprintf() 及其相关函数时,并没有要求或提及 errno(虽然对于某些格式说明符,这些函数被定义为调用 mbrtowc(),该函数可能会在 errno 中设置 EILSEQ)。

POSIX 要求设置 errno

如果遇到输出错误,这些函数将返回负值并设置 errno 以指示错误。

明确提到了 EILSEQ、EINVAL、EBADF、ENOMEM 和 EOVERFLOW:http://pubs.opengroup.org/onlinepubs/9699919799/functions/fprintf.html


1
当C/C++不需要行为(例如在sprintf()失败后设置errno)时,这意味着什么,但POSIX需要吗?我不清楚POSIX在这个问题上的作用 - 如果我编写调用sprintf()的C代码,我猜我正在调用一个libc函数...但是是什么决定了我是否得到了所需的POSIX行为呢? - StoneThrow
2
@StoneThrow,你使用的操作系统决定了这一点。如果是Unix(包括MacOS和Linux),则适用POSIX标准。如果是Windows,则取决于其libc作者的心情。 - Cubbi

5
我总是喜欢采用“试一试”的方法来解决这类问题,特别是在涉及 IT 技术方面。
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

看起来它在使用gcc编译Linux时设置。所以这是好的数据,在errno的man页面中,它提到printf()(和sprintf()相同的家族)可能会改变errno(在底部的示例中)。


+1 作为证明,但 Cubbi 的回答找到了更具体的文档。 - Uyghur Lives Matter
2
请注意,“尝试一下”方法依赖于实施符合标准并且标准不允许不同行为的情况。有时,这种方法可能会误导您... - skyking

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接