【问题标题】:In which cases does printf return a negative value?在哪些情况下 printf 返回负值?
【发布时间】:2020-10-10 08:35:46
【问题描述】:

出于教育目的,我一直在开发自己的 printf 版本,在阅读手册时,我读到该函数在遇到错误时可以返回负值。

起初我认为当格式字符串发生错误时它会返回 -1 / 负值,但事实并非如此。

我开始认为它在遇到一些系统调用错误并且没有成功写入文件描述符时返回-1,然后我测试了这段代码来验证这个想法:

#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    errno = 0;
    int stdout2 = dup(STDOUT_FILENO);
    close(STDOUT_FILENO);
    int ret = printf("Hey", "Hello");
    fprintf(stderr, "%d\t%s\n", ret, strerror(errno));
}

它输出了:

3       Bad file descriptor

设置了Errno,实际上有错误(文件描述符关闭)但没有输出负值。

我在 Linux 上使用 glibc,但我在 MacOS 中也遇到过这种情况。 有什么想法吗?

【问题讨论】:

  • 这是一个错误?您可能是历史上第一个检查 printf() 的返回值的 C 程序员。我从没干过。或者是 close() 失败了。检查一下。
  • 我听说如果它是 UTF-8 语言环境并且字符是无效的 UTF-8,这可能发生在某些系统上(sprintf 也是如此)
  • @KenWhite 您可以将它们全部关闭。我不知道'not yours to close' 可能是什么意思。根据定义,该进程拥有其所有文件描述符。
  • 关闭std* 不是处理守护进程中的标准模式吗?
  • @selbie 并在 shell 中重定向它们。

标签: c++ c glibc libc


【解决方案1】:

所以我阅读了你所有的 cmets,感谢 Peter,我像这样关闭了 stdoud

#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    errno = 0;
    fclose(stdout);
    int ret = printf("Hey", "Hello");
    fprintf(stderr, "%d\t%s\n", ret, strerror(errno));
}

它最终返回-1。但是我很惊讶 printf 不检查系统调用的值并在它们出现时将它们威胁为错误(因为当我直接关闭文件描述符时 printf 不起作用并将 errno 设置为 Bad File Descriptor 但返回数字字符而不是错误)。 感谢您的所有回答!抱歉,如果我留下了一些我刚刚在凌晨 4 点测试的凌乱代码哈哈。

【讨论】:

  • 如果不检查系统调用的值,怎么可能返回 -1?
  • 老实说我不知道​​。对于这种情况,我认为它会检查标准输出的 FILE 结构是否打开。
  • 今晚我会尝试重新检查!
【解决方案2】:

什么情况下 printf 返回负值?

C 标准说(C99 草案):

printf 函数返回传输的字符数,如果 如果 发生输出或编码错误

POSIX 标准说:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 2022-01-22
    • 2015-08-03
    • 1970-01-01
    • 1970-01-01
    • 2016-09-08
    相关资源
    最近更新 更多