簡體   English   中英

如何制作一個簡單的C ++程序,其中沒有刷新std :: cout

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

為了更好地理解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() (當然,你可以使用不干凈的方法,例如直接間接地提升信號)。 根據cppreference ,由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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM