0

如果您像这样抛出未处理的异常main

#include <stdexcept>
#include <iostream>
int main()
{
  std::cout << "Hello World 1" << std::endl;
  throw new std::invalid_argument("A");
  return 0;
}

...然后该过程将终止并显示消息“在抛出'std :: invalid_argument *'实例后调用终止”。
您实际上会在控制台上看到:

Hello World 1
terminate called after throwing an instance of 'std::invalid_argument*'

如果您不打印更多文本std::endl,然后抛出异常:

#include <stdexcept>
#include <iostream>
int main()
{
  std::cout << "Hello World 1" << std::endl;
  std::cout << "Hello World 2";
  throw new std::invalid_argument("A");
  return 0;
}

...然后您将看不到控制台上的第二行:

Hello World 1
terminate called after throwing an instance of 'std::invalid_argument*'

似乎此错误消息会覆盖最后一行,例如\r在它之前打印。

如何解决此行为?

4

1 回答 1

1

第二行实际上并没有被消息覆盖,它永远不会到达控制台!

问题是它std::cout缓冲了它的输出,并且如果进程终止,这个缓冲区不会被刷新。(错误消息实际上打印到标准错误,而不是标准输出。)并且已经发现了这个问题: 各种失败情况下(例如异常),是否可以在程序终止之前自动刷新 std::cout
在我的情况下,我使用它来强制刷新缓冲区:

std::terminate_handler oldTerminateHandler;

void newTerminateHandler()
{
    std::cout << std::endl;
    if (oldTerminateHandler != nullptr)
    {
        oldTerminateHandler();
    }
}

int main()
{
    oldTerminateHandler = std::set_terminate(&newTerminateHandler);
    //...
}
于 2022-02-15T16:06:51.117 回答