什么是错与此打印顺序 [英] Whats wrong with this print order

查看:96
本文介绍了什么是错与此打印顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看看这个code:

 #include<stdio.h>
 #include <unistd.h>
    int main()
    {
            int pipefd[2],n;
            char buf[100];
            if(pipe(pipefd)<0)
                    printf("Pipe error");
            printf("\nRead fd:%d write fd:%d\n",pipefd[0],pipefd[1]);
            if(write(pipefd[1],"Hello Dude!\n",12)!=12)
                    printf("Write error");
            if((n=read(pipefd[0],buf,sizeof(buf)))<=0)
                    printf("Read error");
            write(1,buf,n);
            return 0;
    }

我期望的printf打印阅读FD和之前从管道中读取你好哥们写的fd。但那不是这样的......看到这里。当我在我们学校的计算机实验室尝试过同样的程序我的产量为

I expect the printf to print Read fd and write fd before Hello Dude is read from the pipe. But thats not the case... see here. When i tried the same program in our college computer lab my output was

Read fd:3 write fd:4
Hello Dude!

也少我们的朋友指出,改变printf语句包含\\ n多号字符改变输出顺序...例如.. 的printf(\\ NREAD FD数:%d \\ n个写入FD数:%d \\ n,pipefd [0],pipefd [1]); 意味着读取FD打印则消息你好伙计!然后写fd被打印出来。这是什么行为?
注:走出实验室使用上,我们运行终端一台Linux服务器,我不记得编译器的版本,虽然

also few of our friends observed that, changing the printf statement to contain more number of \n characters changed the output order... for example..printf("\nRead fd:%d\n write fd:%d\n",pipefd[0],pipefd[1]); meant that Read fd is printed then the message Hello Dude! then the write fd is printed. What is this behaviour?? Note: Out lab uses a linux server on which we run terminals, i don't remember the compiler version though.

推荐答案

这是因为的printf 到标准输出的的缓冲,但到标准输出的文件描述符的不是。

It's because printf to the standard output stream is buffered but write to the standard output file descriptor is not.

这意味着行为可以改变的基础上,你有什么样的缓冲。在C语言中,标准输出的的,如果能够确定它被连接到交互设备缓冲。否则,它的完全的缓冲(见<一href=\"http://stackoverflow.com/questions/1716296/why-does-printf-not-flush-after-the-call-unless-a-newline-is-in-the-format-string/4201325#4201325\">here关于为什么会是这样的论文)。

That means the behaviour can change based on what sort of buffering you have. In C, standard output is line buffered if it can be determined to be connected to an interactive device. Otherwise it's fully buffered (see here for a treatise on why this is so).

缓冲线意味着当它看到一个新行会刷新到文件描述符。全缓冲意味着它只会刷新时,缓冲区满(例如,4K价值的数据),或者在流关闭时(或 fflush )。

Line buffered means it will flush to the file descriptor when it sees a newline. Fully buffered means it will only flush when the buffer fills (for example, 4K worth of data), or when the stream is closed (or when you fflush).

在交互方式运行它,刷新之前,发生在,因为的printf 遇到 \\ n 和自动刷新

When you run it interactively, the flush happens before the write because printf encounters the \n and flushes automatically.

然而,当你运行它,否则(如通过重定向输出到文件或在网上的编译器/执行人它可能会做,以捕获presentation数据同样的事情),冲洗发生的的的(因为的printf 每一行后不冲洗)。

However, when you run it otherwise (such as by redirecting output to a file or in an online compiler/executor where it would probably do the very same thing to capture data for presentation), the flush happens after the write (because printf is not flushing after every line).

其实,你并不需要在那里所有的管道东西看到这个动作,按下面的程序:

In fact, you don't need all that pipe stuff in there to see this in action, as per the following program:

    #include <stdio.h>
    #include <unistd.h>
    int main (void) {
        printf ("Hello\n");
        write (1, "Goodbye\n", 8);
        return 0;
    }

当我执行 MYPROG;回声===; MYPROG&GT; myprog.out;猫myprog.out ,我得到:

Hello
Goodbye
===
Goodbye
Hello

,你可以看到不同类型的缓冲使其中的差别。

and you can see the difference that the different types of buffering makes.

如果你想行缓冲不管重定向,你可以尝试:

If you want line buffering regardless of redirection, you can try:

setvbuf (stdin, NULL, _IOLBF, BUFSIZ);

在程序早期 - 这是实现定义的实现是否支持此所以它可能没有任何效果,但我还没有看到很多的地方它不工作

early on in your program - it's implementation defined whether an implementation supports this so it may have no effect but I've not seen many where it doesn't work.

这篇关于什么是错与此打印顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆