std::cout无法打印。

47
有没有任何情况下 std::cout << "hello" 不起作用?我有一个 C++ 程序,在这个程序中,std::cout 似乎什么都不打印,甚至是常量字符串(比如 "hello")。
有没有办法检查 cout 是否能够打开流?有一些成员函数,比如 good()bad(),但我不知道哪一个适合我。

9
啊,缓冲输出,你是个无情又残酷的女人。 - WhozCraig
4
在C语言中没有 std::cout - Lightness Races in Orbit
在窗口系统中,std::cout 可能无法实现,因为存在多个窗口,操作系统不知道要输出到哪个窗口。 - Thomas Matthews
2
永远不要使用cout NULL,否则程序会停止工作。 - relascope
4个回答

64

确保你清空流。这是必需的,因为输出流是有缓冲区的,你无法保证缓冲区会在何时被清空,除非你手动地将其清空。

std::cout << "Hello" << std::endl;

std::endl 会输出一个换行符并刷新流。或者,std::flush 只会执行刷新操作。也可以使用流的成员函数进行刷新:

std::cout.flush();

5
从什么时候开始,向格式化输出流发送一个换行符就会强制刷新?我认为标准并没有关注刷新的内容,而是依赖于成员函数(flush())和操作符(endl)来触发流缓冲区的刷新。这种情况从某个特定的C++标准开始吗? - WhozCraig
@GrijeshChauhan 这并不清空缓冲区(或者不应该:在某些实现中会这样)。 - James Kanze
3
如果在你的实现中出现了刷新操作,那么它就不符合标准。并不是所有实现都能保证会出现这种情况。如果您想要保证换行和刷新,您需要使用 std::endl 或者添加一个 \n 然后调用一些可以触发刷新的成员函数。仅仅添加一个 '\n' 并不能保证能够单独执行这个操作,这是由标准所保证的。 - WhozCraig
1
仅作完整性说明(sftrabbit 的建议更好),但您可以调用 std::cout.rdbuf()->pubsetbuf(NULL, 0); 来关闭缓冲。或者您可以执行 std::cout << std::unitbuf 来激活单元缓冲。 - James Kanze
我和@mahmood有同样的问题。但对我来说似乎没有任何办法。我正在使用Windows 11,在PowerShell中运行可执行文件。当程序遇到带有<<操作符的行时,它就会退出。即使是一个简单的std::cout<< "hello" << endf;,它也会停止。 - undefined
显示剩余5条评论

18

std::cout 在 GUI 应用程序中无法工作!

特定于 MS Visual Studio: 当您想要一个控制台应用程序并使用 MS Visual Studio 时,请将项目属性 "链接器 -> 系统 -> 子系统" 设置为控制台。在 Visual Studio 中创建一个新的 Win32 项目(用于本机 C++ 应用程序)后,默认设置为 "Windows",这会阻止 std::cout 将任何输出放到控制台。


1
更具体地说,您需要使用OutputDebugString。 - rodrigocfd
在“C/C++->预处理器->预处理器定义”中还需要添加“_CONSOLE”,如此处所述:https://dev59.com/unM_5IYBdhLWcg3wjjwp#19406695 - MyNameIsTrez
@rodrigocfd:OutputDebugString()与std::cout无关。OutputDebugString()是Windows中完全不同的设备,而不是控制台。std::cout输出到经典文本控制台(DOS提示符),而OutputDebugString()输出到Windows应用程序可以像MS Visual Studio IDE一样连接的调试端口。使用MS Visual Studio,std::cout和OutputDebugString()之间的区别可能不明显,因为两者的输出都会显示在“输出”日志视图中。 - undefined
在MS Visual Studio中,std::cout的输出将不会显示在“输出”日志视图中。(当我在上面输入我的评论时,我不小心按下了ENTER键,导致未完成的评论没有任何问题。在5分钟后无法进行编辑。我该如何更改这些Stackoverflow设置?) - undefined

10

为了有效地禁用缓冲,您可以调用此函数:

std::setvbuf(stdout, NULL, _IONBF, 0);

或者,您可以在命令行中调用程序并禁用输出缓冲:

stdbuf -o 0 ./yourprogram --yourargs

记住,出于性能原因,通常不会这样做。


1
这帮助我修复了标准输出,在传输一定量(随机)数据后停止打印的问题。flush()在这里没有起作用。非常感谢。 - kyb
非常奇怪,到目前为止我尝试了std::endl、std::flush、stdbuf、std::setvbuf,但是过了一段时间后,标准输出就消失了,不过我仍然可以与程序进行交互,这意味着程序在运行,只是标准输出没有显示出来。 - undefined

9

很可能是由于缓存(你写的内容最终会在std::cout的缓存中而不是输出中)导致std::cout不起作用。

你可以尝试以下任一方法:

  • flush std::cout explicitly:

    std::cout << "test" << std::flush; // std::flush is in <iostream>
    

    std::cout << "test";
    std::cout.flush(); // explicitly flush here
    

    std::cout << "test" << std::endl; // endl sends newline char(s) and then flushes
    
  • use std::cerr instead. std::cerr is not buffered, but it uses a different stream (i.e. the second solution may not work for you if you're interested in more than "see message on console").


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接