首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在关闭stdout之后调用printf会发生什么?

在关闭stdout之后调用printf会发生什么?
EN

Stack Overflow用户
提问于 2019-11-29 01:42:14
回答 1查看 767关注 0票数 1

我尝试了下面的代码,但屏幕上什么也没有显示。

代码语言:javascript
运行
复制
close(STDOUT_FILENO); 
printf("Child output something\n");

是否只是找不到标准输出,然后中止数据?

我想知道printf是否写入了一些数据,因为我不能打印返回值,所以我将其输出到某个文件中。

代码语言:javascript
运行
复制
close(STDOUT_FILENO); 
int res = printf("output something\n");
open("./log.output", O_CREAT|O_WRONLY|O_TRUNC, S_IRWXU);
printf("%d", res);   // return 17

所以printf可以工作,但我不知道它写到哪里。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-29 05:14:43

您看到此结果的原因与缓冲有关。通常,连接到终端的文件是行缓冲的,而所有其他文件都是块缓冲的。stderr是无缓冲的。

当您关闭stdout时,它不再附加到终端,因此它是块缓冲的,而不是行缓冲的。您尝试写入的字节数少于缓冲区大小(通常是512的倍数),因此printf愉快地将其复制到缓冲区,不做任何其他操作。如果您使用printf编写了适当数量的数据,您会发现它确实在这一点上失败了。

可以通过调用fflush(stdout)来验证类似的行为

代码语言:javascript
运行
复制
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main(void)
{
    close(STDOUT_FILENO);
    int res = printf("output something\n");
    fprintf(stderr, "%d\n", res);
    res = fflush(stdout);
    fprintf(stderr, "%d %s\n", res, strerror(errno));
}

最后一行将输出-1 Bad file descriptor,这表明写入标准输出的尝试如预期的那样失败并返回EBADF。如果需要验证数据是否已写入,则必须根据需要调用fflushfsync

请注意,通常情况下,您不希望关闭这三个默认文件描述符中的任何一个,因为无论何时打开新的文件描述符,它都将使用最小的未使用编号,并替换其中一个标准流。如果您的程序的一个单独部分试图在不进行检查的情况下写入其中一个流,它可能会写入意外的文件,从而损坏该文件。安全的做法是将这些流重定向到/dev/null

log.outputopen调用恰好完成了我刚才提到的事情,即再次打开文件描述符1 (stdout)。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59094054

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档