如何制作一个简单的C++程序,其中std::cout不被刷新



为了更好地理解C++中的缓冲流,我想编写一个简单的程序,其中std::cout缓冲区在终止之前不会刷新。 由于我已经读到std::cout在正常终止时被刷新,所以我尝试抛出运行时错误。 我也避免使用std::endl,因为我知道这会强制冲洗。 第一次尝试:

//file noflush.cpp
#include <iostream>
int main() {
    std::cout << "Don't write me to the console!";
    throw 0;
}

使用 g++ 编译,从终端调用:

$ ./noflush
libc++abi.dylib: terminating with uncaught exception of type int
Don't write me to the console!Abort trap: 6

即使我强制出现运行时错误,似乎缓冲区仍然会在终止时刷新。 是否可以在缓冲区中"搁浅"一些数据,使其未写入设备?

这不是标准的 c++,但在 POSIX 中,你可以发送一个 "kill" 信号来杀死正在运行的进程。这将停止执行,而不进行清理,例如刷新缓冲区。

编辑:我意识到信号不仅是POSIX,而且实际上是C标准库的一部分(并包含在C++标准库中)。

#include <csignal>
// ...
std::cout << "Don't write me to the console!";
std::raise(SIGKILL);

据我所知,没有标准的兼容和干净的方法来避免在程序终止之前std::cout flush()(但是,当然,您可以使用不干净的方法,例如直接或间接发出信号)。根据 cpp 首选项,由 std::cout 控制的实际缓冲区类型是实现定义的,但派生自 std::streambuf ,这似乎不允许以模拟缓冲区的静默吞噬的方式进行公共访问。

此外,正如我在评论中指出的那样,即使是异常的程序终止(通过std::terminate()std::abort()也可能不会关闭开放资源,因此这再次定义实现。

通过以下示例,我可以在 gcc 4.8.3 中创建您想要的行为:

#include <iostream>
#include <vector>
int main()
{
    std::string str;
    for(unsigned long int i = 0; i < 10000; ++i)
        str += "Hello ! ";
    str += "END";
    std::cout << str;
    std::vector<double>* p;
    p->push_back(1.0);
    delete p;
    std::cout << "STILL ALIVE !" << std::endl;
    return 0;
}

然后,输出为:

你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好!你好![...]你好!分段错误

我们可以看到比END之前没有打印出分割错误。

如果我

猜对了,您想捕获或忽略输出以std::cout

#include <iostream>
#include <sstream>
int main()
{
    // Capture the output to `std::cout`
    {
        std::cout << "[Capture Output]" << std::endl;
        std::stringstream cpature;
        auto restore = std::cout.rdbuf(cpature.rdbuf());
        std::cout << "... captured output ..." << std::endl;
        std::cout.rdbuf(restore);
        std::cout << "[Enable Output]" << std::endl;
        // Display the cpatured output.
        std::cout << cpature.rdbuf();
    }
    std::cout << std::endl;
    // Even more drasticly: Ignore the output to `std::cout`
    {
        std::cout << "[Ignore Output]" << std::endl;
        auto restore = std::cout.rdbuf(nullptr);
        std::cout << "... ignored output ..." << std::endl;
        std::cout.rdbuf(restore);
        std::cout << "[Enable Output]" << std::endl;
    }
    std::cout << "[End]n";
}
#include <iostream>
#include <sstream>
#include <vector>
int main()
{
    std::stringstream cpature;
    auto restore = std::cout.rdbuf(cpature.rdbuf());    
    std::cout.rdbuf(restore);
    for(unsigned long int i = 0; i < 10000; ++i)
        std::cout <<"Hello ! "  << std::endl;
    std::cout << "END"  << std::endl;
    std::cout << cpature.rdbuf();
    std::vector<double> *p;
    p->push_back(1.0);
    delete p;
    std::cout << "STILL ALIVE !" << std::endl;
}

相关内容

  • 没有找到相关文章

最新更新