我刚刚学习了文件描述符,我正在try 一些代码来理解它的工作方式.在编写下面的程序时,我希望第一个printf应该写入控制台,然后,因为我关闭了标准输出并打开了一个新文件,所以我希望它返回最小的文件描述符1(因为它是可用的,因为我之前关闭了它).然后,我期待第二个printf写入文件file.txt.

#include<fcntl.h>
#include<stdio.h>
#include<unistd.h>

int main()
{
        printf("before close");
        close(1);
        int x1 = open("./file.txt", O_RDWR);
        printf("after close, the file descriptor is %d\n", x1);
}

但是,当我执行此命令时,控制台不会打印任何内容,但所有内容都会打印到文件.txt,即

file.txt

before closeafter close, the file descriptor is 1

为什么会这样呢?

推荐答案

这是一个buffering期的问题.

输出到stdout(这是printf次写入的位置)是buffered.当stdout连接到交互终端时,它是line buffered,这意味着输出被刷新(实际上写入)在换行符上.

因此,如果希望将第一个输出写入控制台,请在输出中添加换行符:

printf("before close\n");

作为替代方案,您可以使用fflush(stdout)来显式刷新缓冲区.但请注意,由于您不打印换行符,因此输出可能会进入shell 提示符.或者,shell 程序可以打印一个特殊字符来表示缺少换行符,这有时会让人感到困惑.


当前代码的情况是,第一个printf次调用的输出留在缓冲区中,并将在第二次调用导致缓冲区刷新时写入.到那时,输出将被"重定向"到该文件.


注意,缓冲是在调用main函数之前设置的.仅仅因为您通过关闭和重新打开文件描述符来更改stdout的目的地,并不意味着缓冲区将会更改.在closeopen调用之后,您的程序仍将被行缓冲.

如果你想改变stdout的缓冲,你需要使用setvbuf函数.

C++相关问答推荐

ISO_C_BINDING,从Fortran调用C

如何正确地索引C中的 struct 指针数组?

使用NameSurname扫描到两个单独的字符串

正确的TCP/IP数据包 struct

I2C外设在单次交易后出现故障

如何使用C++在控制台中以彩色打印被阻止的客户端

OpenSSL:如何将吊销列表与SSL_CTX_LOAD_VERIFY_LOCATIONS一起使用?

指向不同类型的指针是否与公共初始序列规则匹配?

MacOS下C++的无阻塞键盘阅读

按长度对argv中的单词进行排序

使用ld将目标文件链接到C标准库

C-try 将整数和 struct 数组存储到二进制文件中

隐藏测试用例无法在c程序中计算位数.

在文件描述符上设置FD_CLOEXEC与将其传递给POSIX_SPOWN_FILE_ACTIONS_ADCLOSE有区别吗?

变量值不正确的问题

在C中,为什么这个带有递增整数的main函数从不因溢出而崩溃?

从管道读取数据时丢失

设置具有非零终止字符串的大整数

React Native Android C++ TurboModules 静态 C 库链接问题

为什么简单的 ELF 二进制文件中存在重叠和未对齐的段?