【问题标题】:C/Unix Strange behaviour while using system calls and printf使用系统调用和 printf 时的 C/Unix 奇怪行为
【发布时间】:2013-05-11 07:23:56
【问题描述】:

我是一个新手,试图真正了解系统编程。在下面的程序中,我正在读取一个名为“temp1”的文件(包含 1 2 3 4)并将其内容打印到标准输出。但是,我还想检查 open 返回的文件描述符的值。如果我在第 5 行的 printf 调用中包含 '\n',则输出会先打印值 filep,然后再打印文件的内容。但是如果我删除换行符,文件的内容会首先打印,然后是 filep 的值。 为什么会发生这种情况?

     int main(){
     char buf[BUFSIZ];
     int n, filep;

     // Open the file
     filep = open("temp1", 'r');
     printf("%d\n", filep); // the newline alters program behaviour

     while((n=read(filep, buf, BUFSIZ)) > 0)
         write(1, buf, n);
     return 0;
    }

我使用的是 gcc 4.6.3。

【问题讨论】:

  • @GrijeshChauhan : ?? open 系统调用返回一个文件描述符,它是一个整数。 printf 打印该文件描述符的值。
  • 是的,你是对的! ...考虑我评论的第二点

标签: c unix system-calls


【解决方案1】:

<stdio.h> 类似 printf 的函数被缓冲。输出函数只会不时调用write(2) 系统调用,通常像printf 等输出函数只会进入内部FILE 缓冲区。

stdout 在输出到终端时是行缓冲的(请参阅isatty(3))。因此,如果printf 格式字符串以\n 结尾,则会发生写入。

您可以在 while 循环之前添加 fflush(stdout);fflush(NULL); 调用。

fflush(3)setvbuf(3)

如果您不刷新 stdout(使用 printf 格式字符串中的 \n,或者通过 fflushfclose 显式刷新),则缓冲区仅在 main 的末尾刷新(通过一些隐式atexit(3) ...)

所以发生在你身上的是(没有\n)数据保留在stdout 缓冲区中,并且实际上仅在程序退出时写入(由stdio 库中的write(2)) .

阅读advanced linux programming

【讨论】:

  • @Basile:谢谢。我从你的扩展答案中得到了它。很好的解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-07
  • 2016-04-30
相关资源
最近更新 更多