为什么打印时不保留顺序,先用cerr然后用cout? [英] Why the order is not preserved when printing something, first with cerr and then cout?

查看:25
本文介绍了为什么打印时不保留顺序,先用cerr然后用cout?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有带有 Xubuntu 14.04 的 g++ 4.8.4 版编译器.在我的 OpenCV 代码(用 Eclipse CDT 编写)中,我连续写了以下三行:

I have g++ version 4.8.4 compiler with Xubuntu 14.04. In the midst of my OpenCV code (written in Eclipse CDT), I wrote the following three lines consecutively:

/* Some codes here*/
cerr << "No match found. # of false positives: " << falsePositives << endl;
cout << "Press a key to continue..." << endl;
waitKey(0);

结果如下:

Press a key to continue...
No match found. # of false positives: 1
/*there is a blank line*/

为什么这两行的顺序在执行时发生了变化?前几行根本没有并行代码,但它们似乎像并行(同时)一样工作.

Why the order of those two lines changed at the execution time? There is no parallel code at all in the previous lines but they seems to work like parallel (at the same time).

我知道 cerr 没有缓冲,而 cout 是缓冲的(这意味着,afaik,cerr 比 cout 慢);但是,无论如何,执行顺序不应该改变吗?那个空行来自哪里?(可能来自这些结尾之一,但哪一个?)

I know that cerr is not buffered whereas cout is buffered (which means, afaik, cerr is slower compared to cout); however, no matter what, shouldn't the order of execution be changed? And where does that blank line comes from? (probably from one of those endls but which one?)

有人能解释一下这两行是怎么回事吗?

Can someone explain what is going on those two lines?

非常感谢.

我不使用 ubuntu,我使用 Xubuntu 14.04.抱歉那个错误,我的脑子太乱了,但我认为它不会影响结果.我使用 Eclipse 提供的控制台来显示它们.我试图将 std:: 前缀附加到所有 cout、cerr、endl.结果是一样的.

I don't use ubuntu, I use Xubuntu 14.04. Sorry for that mistake, my mind was too messy but I think it does not effect the result. I use Eclipse's provided console to display them. I tried to append std:: prefix to all cout, cerr, endl. The result is same.

有趣的一点是,当我刚写了一个新文件时,包括:

The interesting point is that when I just wrote a new file including:

#include <iostream>
#include <cstdlib>
int main()
{       
    std::cerr << "No match found. # of false positives: " << 2 << std::endl;
    std::cout << "Press a key to continue..." << std::endl;

    return 0;
}

我通过使用 xfce4-terminal 和 g++ 编译器获得了预期的输出(首先是 cerr,然后是 cout).

I got the expected output(first cerr and then cout) by using xfce4-terminal and g++ compiler.

使用Eclipse CDT时出现问题.我还想提醒大家我在 OpenCV 上工作.

The problem occurs when using Eclipse CDT. I also want to remind all of you that I work on OpenCV.

Chris Dodd 的第四个建议:

Chris Dodd's 4th suggestion:

您的代码实际上与您在上面发布的内容不同,差异虽然看似不重要,但实际上至关重要."

当然,我的代码确实包含我输入的内容以外的内容,但在这些行之前还有很多,我的意思是大量计算等.但是,可能存在我无法意识到的相关部分.此外,我根本没有在这些行之前将 stdout 和/或 stderr 重定向到不同的设备/文件/管道.

Of course my code does contain other than what I typed but there are lots of, I mean lots of computation etc. before those lines. However, there might be relating parts before which I could not realise. Also, I didn't redirected stdout and/or stderr to different devices/files/pipes before those lines at all.

编辑 2:当我在 Eclipse CDT 的 Debug 模式下执行程序时,按照流水线,

EDIT 2: When I execute the program in the Debug mode of Eclipse CDT, following assembly lines,

cerr 行之后执行以下(当然还有其他汇编代码):

After cerr line the followings are executed (as well as other assembly codes of course):

callq 0x403500 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
callq 0x403470 <_ZNSolsEi@plt>
callq 0x403770 <_ZNSolsEPFRSoS_E@plt>

cout 行之后执行以下(当然还有其他汇编代码):

After cout line the followings are executed (as well as other assembly codes of course):

callq 0x403500 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
callq 0x403770 <_ZNSolsEPFRSoS_E@plt>
callq 0x403670 <_ZN2cv7waitKeyEi@plt>

它们都给出相同的错误信息:

and they all give the same error message:

没有可用于std::basic_ostream >& std::operator<< >(std::basic_ostream >&, char const*)@plt at 0x403500"

No source available for "std::basic_ostream >& std::operator<< >(std::basic_ostream >&, char const*)@plt at 0x403500"

该过程继续执行其他汇编代码行而不会终止.

and the process continues with other lines of assembly code without termination.

PS:当我注释掉除这两行之外的所有内容时,它按预期工作.因此,我的结论是,在这些行之前可能有相关的代码部分,但我无法弄清楚.

PS: When I commented out everthing but those two lines, it works as expected. Thus, my conclusion is that, there may be relevant code part before those lines but I couldn't figure them out.

推荐答案

std::cerrstd::cout 是不同的流,它们不同步.因此,您真的无法假设两者的输出如何显示.在这种情况下,输出恰好在错误之前显示.

std::cerr and std::cout are different streams and they are not synchronized. So you really can't assume anything about how output to both gets shown. In this case, the output happens to be shown before the error.

可以依赖任一流中的顺序.

You can rely on the order within either stream.

此外,std::cout 是缓冲的,而 std::cerr 不是,这通常会导致此类问题,但因为您使用的是 std::endl (刷新流)这并不真正适用于您的情况.

Additionally, std::cout is buffered and std::cerr is not, and that often causes this kind of problem, but because you are using std::endl (which flushes the stream) this doesn't really apply in your case.

这篇关于为什么打印时不保留顺序,先用cerr然后用cout?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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