C++;当输入到控制台时,程序停止生成控制台输出 我有一个C++程序(MSVC 2017),它通过STD::CUT不断输出调试信息。但是,有时当我与控制台进行物理交互时(例如,意外地单击它),它会停止生成输出。这意味着,尽管程序继续运行并完成正确的操作,但没有打印任何内容

C++;当输入到控制台时,程序停止生成控制台输出 我有一个C++程序(MSVC 2017),它通过STD::CUT不断输出调试信息。但是,有时当我与控制台进行物理交互时(例如,意外地单击它),它会停止生成输出。这意味着,尽管程序继续运行并完成正确的操作,但没有打印任何内容,c++,console,output,interaction,C++,Console,Output,Interaction,有没有办法解决这个问题?使用“std::cout.setf(std::ios::unitbuf);”删除std::cout缓冲区无效 样本: #include <iostream> int main() { int i = 0; while (true) { i++; if (i%100000000 == 0) std::cout << i++ << "\n"; } return 0; } #包括 int main() {

有没有办法解决这个问题?使用“std::cout.setf(std::ios::unitbuf);”删除std::cout缓冲区无效

样本:

#include <iostream>

int main()
{
  int i = 0;
  while (true) {
    i++;
    if (i%100000000 == 0) std::cout << i++ << "\n";
  }
  return 0;
}
#包括
int main()
{
int i=0;
while(true){
i++;

如果(i%100000000==0)std::cout这就是我复制测试所做的-编写
mcve.cc

#include <iostream>
int main()
{
  for (char i = 0;; ++i) std::cout << (int)i << std::flush;
  return 0;
}
这起作用–禁用QuickEdit(单击控制台窗口不再停止输出)

然而,如果没有这个技巧,它也应该会起作用。(我不明白这一点,这让我很烦恼。)思考了一会儿后,我想到了一个启发性的想法。是不是快速编辑后的
std::cout
bad()

因此,我制作了第三个版本。由于我不能使用
cout
put,我修改了
I
,我可以在调试器中看到它。(实际上,
std::cout::good()
的返回也会显示出来,但分配给
I
更能说明问题。)

我不确定我更喜欢哪两种解决方案:

  • 前者的侵入性最小(只是对
    main()
    开头的一个添加)
  • 后者是纯C++(没有平台特定代码),我更喜欢一般。

关于非Windows平台,我想听听大家的意见

我不记得在Linux(也不包括Irix或Solaris——我以前使用过的操作系统)上见过这样的QuickEdit问题。在该系统上,选择由Xterm/X11处理(在我的例子中),超出了流I/O的范围

那么,是否有可能
std::cout
在该系统上变得不好(假设输出中没有编码错误)


最后,我找到了一种可移植的非侵入性方法(以多线程为代价):


#包括。根据此链接中接受的答案,它是有保证的(或至少是必需的)从C++11开始。

你确定这是你的程序的问题,而不是控制台本身的问题吗?当输出停止时,你实际上在做什么?如果不是控制台而是你的程序,请尝试创建一个你可以展示给我们的。我知道这一点。(这也曾经困住了我。)这意味着控制台中的选择处于挂起状态。按[ESC]或[ENTER]将中止/完成挂起的选择。当选择处于挂起状态时,应用程序将停止,您可以在调试器中看到它正在等待…可能是“Win32”中的某个锁代码。我甚至不知道可以禁用应用程序中的选择。我只是找到了一个关于此的Q/a:。谢谢,下面是一个最小的示例:#include int main(){int I=0;while(true){I++;if(I%100000000==0)std::cout press escape->program继续运行(我在任务管理器中看到它),但没有输出我可以做得更短:
#include int main(){for(;)std::cout刚刚找到第三个解决方案-答案扩展非常感谢您的帮助!当快速编辑模式(例如Mark)时,线程方法对我不起作用处于活动状态。cout仍将冻结。MSVC2015/Win10@md_nr_gen只要在控制台中标记了某些内容,这是正确的。如果在控制台中完成复制或使用[ESC]中止标记,会发生什么?在这种情况下输出是否继续?(在我的情况下,是这样的。我已经在Windows 10上用VS2013和
cmd
进行了测试。)BTW.该示例只涵盖<代码> STD::CUT。如果您的输出转到<代码> STD::CURR ,解决方案可能需要考虑这一点。(没有测试)@md_nr_gen关于
std::cout
std::cerr
:我刚刚修改了程序,使其交替在
std::cout
std::cerr
上打印。在控制台中标记一些文本并按[ESC]后,跳过了错误输出。只有
std::cout
工作正常。
#include <iostream>
#include <Windows.h>
int main()
{
  // disable QuickEdit mode in Console
  HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE);
  DWORD prev_mode;
  GetConsoleMode(hInput, &prev_mode); 
  SetConsoleMode(hInput, prev_mode & ~ENABLE_QUICK_EDIT_MODE);
  // start test
  for (char i = 0;; ++i) std::cout << (int)i << std::flush;
  // done (never reached)
  return 0;
}
#include <iostream>
#include <Windows.h>
int main()
{
  for (char i = 0;; ++i) {
    if (!std::cout.good()) i = 0;
    std::cout << (int)i << std::flush;
  }
  return 0;
}
#include <iostream>
#include <Windows.h>
int main()
{
  for (char i = 0;; ++i) {
    if (!std::cout.good()) std::cout.clear();
    std::cout << (int)i << std::flush;
  }
  return 0;
}
#include <atomic>
#include <iostream>
#include <thread>

int main()
{
  // spawn extra thread to clean cout periodically
  std::atomic<bool> exitThreadClearCOut = false;
  std::thread threadClearCOut([&]() {
    while (!exitThreadClearCOut) {
      if (!std::cout.good()) std::cout.clear();
      std::this_thread::sleep_for(std::chrono::milliseconds(100));
      // 100 ms - nearly non-perceptable for humans but an "eternity" for modern CPUs
    }
  });
  // start main work
  for (char i = 0;; ++i) {
    std::cout << (int)i << std::flush;
  }
  // finish/join thread to clean cout periodically
  exitThreadClearCOut = true;
  threadClearCOut.join();
  // done
  return 0;
}