Подтвердить что ты не робот

Как сделать простую программу на С++, в которой std:: cout не очищается

Чтобы лучше понять буферизованные потоки в С++, я хотел бы написать простую программу, в которой буфер 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

Даже когда я заставляю ошибку времени выполнения, кажется, что буфер по-прежнему загорается при завершении. Возможно ли "запрячь" некоторые данные в буфере, оставив его неписанным для устройства?

4b9b3361

Ответ 1

Это не стандартный С++, но в POSIX вы можете отправить сигнал "kill", чтобы убить текущий процесс. Это остановит выполнение без очистки, например, сбросных буферов.

Edit: я понял, что сигналы - это не только POSIX, но и фактически часть стандартной библиотеки C (и включены в стандартную библиотеку С++).

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

Ответ 2

Насколько я могу судить, нет стандартного совместимого и чистого способа избежать std::cout до flush() до завершения программы (но, конечно, вы можете использовать нечистые методы, например, повышение сигнала либо или косвенно). Согласно cppreference, фактический тип буфера, контролируемый std::cout, представляет собой реализацию, определенную, но полученную из std::streambuf, который, по-видимому, не позволяет публичному доступу таким образом, чтобы эмулировать молчаливое глотание буфера.

Кроме того, как я заметил в комментарии, даже аномальное завершение программы (через std::terminate() или std::abort() может закрываться или не закрываться открытые ресурсы, так что это снова реализация определена.

Ответ 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;
}

Затем вывод:

Привет! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! Здравствуйте! [...] Здравствуйте! Ошибка сегментации

Мы можем видеть, что END не печатается перед ошибкой сегментации.

Ответ 4

Если вы правильно поняли, вы хотите захватить или проигнорировать вывод на 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";
}

Ответ 5

#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;
}