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

Есть ли реализация null std:: ostream в С++ или библиотеках?

Я ищу реализацию std::ostream, которая действует как /dev/null. Он просто проигнорировал бы все, что было передано ему. Существует ли такая вещь в стандартных библиотеках или Boost? Или мне нужно катиться самостоятельно?

4b9b3361

Ответ 1

Если у вас есть boost, тогда существует реализация null ostream и istream, доступная в boost/iostreams/device/null.hpp. Суть его:

#include "boost/iostreams/stream.hpp"
#include "boost/iostreams/device/null.hpp"
...
boost::iostreams::stream< boost::iostreams::null_sink > nullOstream( ( boost::iostreams::null_sink() ) );
...

Ответ 2

Самое простое решение - просто использовать нераспечатанный std::ofstream. Эта приведет к возникновению состояния ошибки в потоке, но большинство выходов не будут Проверь это; обычная идиома заключается в том, чтобы оставить чек до конца, после закрыть (что бы вы указали в коде, который вы написали, где вы знаете, что поток должен быть недействительным).

В противном случае это довольно просто реализовать: просто создайте streambuf, который содержит небольшой буфер и устанавливает его в overflow (всегда возвращающий успех). Обратите внимание, что это будет медленнее, чем нераспечатанный файл; различные операторы >> все равно будут преобразование (которое они не делают, если поток имеет состояние ошибки).

EDIT:

class NulStreambuf : public std::streambuf
{
    char                dummyBuffer[ 64 ];
protected:
    virtual int         overflow( int c ) 
    {
        setp( dummyBuffer, dummyBuffer + sizeof( dummyBuffer ) );
        return (c == traits_type::eof()) ? '\0' : c;
    }
};

Обычно для обеспечения класса удобства, полученного из istream или ostream, который будет содержать экземпляр этого который он использует. Что-то вроде:

class NulOStream : private NulStreambuf, public std::ostream
{
public:
    NulOStream() : std::ostream( this ) {}
    NulStreambuf* rdbuf() const { return this; }
};

Или вы можете просто использовать std::ostream, передав адрес streambuf к нему.

Ответ 3

Если вы установите badbit в потоке, он ничего не выведет:

#include <iostream>

int main() {
    std::cout << "a\n";

    std::cout.setstate(std::ios_base::badbit);
    std::cout << "b\n";

    std::cout.clear();
    std::cout << "c\n";
}

Выходы:

a
c

Ответ 4

Я знаю, что это очень старая тема, но я хотел бы добавить это всем, кто ищет такое же решение без ускорения и быстрого.

Выше я объединил три разных предложения и одно письмо непосредственно в /dev/null (так что это касается ядра.)

Удивительно, но NullStream, получивший наибольшее количество голосов, показал худшие результаты.

Вот результаты для 100 000 000 записей:

a) /dev/null : 30 seconds
b) NullStream: 50 seconds
c) badbit    : 16 seconds (the winner in speed, but cannot test for errors!)
d) boost     : 25 seconds (the ultimate winner)

Вот тестовый код

#include <iostream>
#include <fstream>
#include <time.h>
#include <boost/iostreams/stream.hpp>

class NullStream : public std::ostream {
    class NullBuffer : public std::streambuf {
    public:
        int overflow( int c ) { return c; }
    } m_nb;
public:
    NullStream() : std::ostream( &m_nb ) {}
};

int test( std::ostream& ofs, const char* who ) {
    const time_t t = time(NULL);
    for ( int i = 0 ; i < 1000000000 ; i++ )
        ofs << "Say the same" ;
    std::cout << who << ": " << time(NULL) - t << std::endl;
}

void devnull() {
    std::ofstream ofs;
    ofs.open( "/dev/null", std::ofstream::out | std::ofstream::app );
    test(ofs, __FUNCTION__);
    ofs.close();
}

void nullstream() {
    NullStream ofs;
    test(ofs, __FUNCTION__);
}

void badbit() {
    std::ofstream ofs;
    ofs.setstate(std::ios_base::badbit);
    test(ofs, __FUNCTION__);
}

void boostnull() {
    boost::iostreams::stream< boost::iostreams::null_sink > nullOstream( ( boost::iostreams::null_sink() ) );
    test(nullOstream, __FUNCTION__);
}

int main() {
    devnull();
    nullstream();
    badbit();
    boostnull();
    return 0;
}

РЕДАКТИРОВАТЬ

Самое быстрое решение - где мы используем бадбит - имеет обратную сторону. Если программа проверяет, успешно ли записан вывод - и я понятия не имею, почему программа не должна этого делать, - то из-за этого бадбита произойдет сбой. Поэтому, занявший второе место - повышение - это победитель.

Ответ 5

Для меня самый простой способ был бы:

#include <fstream>

std::ostream* out = &std::cout;

std::ostream* nullstream() {
    static std::ofstream os;
    if (!os.is_open())
        os.open("/dev/null", std::ofstream::out | std::ofstream::app);
    return &os;
}

int main() {
    *out << "Normal output\n";

    out = nullstream();
    *out << "Will not visible\n";

    out = &std::cout;
    *out << "Back again\n";

    return 0;
}

Или используйте флаг "badbit" вместо "/dev/null" в функции "nullstream", как описано выше.

std::ostream* nullstream() {
    static std::ofstream os;
    static bool flag_set = false;
    if (!flag_set) {
        os.setstate(std::ios_base::badbit);
        flag_set = true;
    }
    return &os;
}

Ответ 6

Пусть это решение преодолевает проблему производительности без использования повышения:

#include <ostream>

class dev0_buffer : public std::streambuf
{
   //called usually for n-characters
   std::streamsize xsputn (const char* s, std::streamsize n) override { return n; }

   //may not required due it not called anymore
   int overflow (int c)  override { return c; } 
} nirwana;

class dev0_stream : public std::ostream
{
   public:
    dev0_stream(): std::ostream(&nirwana){}
};