【发布时间】:2013-01-24 13:07:15
【问题描述】:
根据http://linux.die.net/man/3/sprintf和http://www.cplusplus.com/reference/cstdio/sprintf/sprintf()和family返回成功写入的字符数。失败时,返回一个负值。我假设如果格式字符串格式错误可能会发生错误,因此负返回值可能表示malloc() 错误以外的其他内容。 errno 是否设置为指示错误是什么?
【问题讨论】:
根据http://linux.die.net/man/3/sprintf和http://www.cplusplus.com/reference/cstdio/sprintf/sprintf()和family返回成功写入的字符数。失败时,返回一个负值。我假设如果格式字符串格式错误可能会发生错误,因此负返回值可能表示malloc() 错误以外的其他内容。 errno 是否设置为指示错误是什么?
【问题讨论】:
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
【讨论】:
sprintf() 失败后设置 errno)但 POSIX 需要时,这意味着什么?我不清楚 POSIX 在哪里适合 - 如果我编写了名为 sprintf() 的 C 代码,我想我正在调用一个 libc 函数......但是什么决定了我是否得到了 POSIX 所需的行为?
当我有这样的问题时,我总是喜欢“试试看”的方法。
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(在底部的示例中)。
【讨论】: