简体   繁体   English

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

[英]How to make a simple C++ program in which std::cout is not flushed

In an effort to better understand buffered streams in C++, I would like to write a simple program in which the std::cout buffer is NOT flushed before termination. 为了更好地理解C ++中的缓冲流,我想编写一个简单的程序,在终止之前不会刷新std::cout缓冲区。 Since I have read that std::cout is flushed on normal termination, I tried throwing a runtime error. 因为我已经读过std::cout在正常终止时被刷新,所以我尝试抛出运行时错误。 I also avoided using std::endl , as I understand that forces a flush. 我也避免使用std::endl ,因为据我所知强制刷新。 First attempt: 第一次尝试:

//file noflush.cpp
#include <iostream>

int main() {
    std::cout << "Don't write me to the console!";
    throw 0;
}

Compile with g++, call from terminal: 用g ++编译,从终端调用:

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

Even when I force a runtime error, it seems the buffer still gets flushed on termination. 即使我强制运行时出错,看起来缓冲区在终止时仍然会被刷新。 Is it possible to "strand" some data in the buffer, leaving it unwritten to the device? 是否有可能在缓冲区中“绑定”某些数据,使其不被写入设备?

This is not standard c++, but in POSIX, you can send a "kill" signal to kill the running process. 这不是标准的c ++,但在POSIX中, 你可以发送一个“kill”信号来杀死正在运行的进程。 This will stop the execution without cleanup such as flushing buffers. 这将停止执行而不进行清理,例如刷新缓冲区。

Edit: I realized that signals are not only POSIX but actually part of C standard library (and included in the C++ standard library). 编辑:我意识到信号不仅是POSIX,而且实际上是C标准库的一部分(并包含在C ++标准库中)。

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

As far as I can tell, there is no standard compliant and clean way to avoid std::cout to flush() before program termination (but, of course, you can use unclean methods, eg raising a signal either directly or indirectly ). 据我所知,在程序终止之前没有标准的兼容和干净的方法来避免std::cout flush() (当然,你可以使用不干净的方法,例如直接间接地提升信号)。 According to cppreference , the actual buffer type controlled by std::cout is implementation defined but derived from std::streambuf , which does not appear to allow public access in a way that would emulate silent swallowing of the buffer. 根据cppreference ,由std::cout控制的实际缓冲区类型是实现定义的,但是从std::streambuf派生,它似乎不允许以模拟缓冲区静默吞咽的方式进行公共访问。

Further, as I noted in a comment, even abnormal program termination (via std::terminate() or std::abort() may or may not close open resources, so this is again implementation defined. 此外,正如我在评论中所指出的,即使异常程序终止(通过std::terminate()std::abort()可能会也可能不会关闭开放资源,因此这又是实现定义的。

With the following example, I can create the behaviour you want with gcc 4.8.3 : 通过以下示例,我可以使用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;
}

Then, the output is : 然后,输出是:

Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! Hello ! 你好 ! [...] Hello ! [...] 你好 ! Segmentation fault 分段故障

We can see than END is not printed before the segmentation fault. 我们可以看到在分段故障之前没有打印出END

If I get you right, you want to capture or ignore the output to std::cout : 如果我说得对,你想要捕获或忽略输出到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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM