Печать в никуда с ostream - PullRequest
       2

Печать в никуда с ostream

8 голосов
/ 19 октября 2011

Я бы хотел отправить данные в никуда, я имею в виду, что я не хочу печатать данные ни в консоли, ни в файле, но мне нужен какой-то объект std::ostream.Как это сделать?

Ответы [ 5 ]

12 голосов
/ 19 октября 2011

Я использовал:

std::ostream bitBucket(0);

в последнее время без проблем, хотя он был помечен как имеющий потенциальные проблемы, если смотреть на него под определенным углом (см. Ссылку ниже).

Помимо: Из того, что я понимаю (и я не полностью уверен в этом), этот вызов в конечном итоге в конечном итоге вызовет basic_ios::init(0) и, поскольку это указатель NULL при передаче он устанавливает состояние потока, возвращаемое функцией rdstate(), в значение badbit.

Это, в свою очередь, препятствует тому, чтобы поток выводил больше информации, вместо этого просто отбрасывая ее.

Следующая программа показывает это в действии:

#include <iostream>

int main (void) {
    std::ostream bitBucket(0);
    bitBucket << "Hello, there!" << std::endl;
    return 0;
}

На странице, где я получил его от , также было это решение, возможно, более чистого (слегка измененное для удаления дублирования моего первого решения выше):

#include <iostream>

class null_out_buf : public std::streambuf {
    public:
        virtual std::streamsize xsputn (const char * s, std::streamsize n) {
            return n;
        }
        virtual int overflow (int c) {
            return 1;
        }
};

class null_out_stream : public std::ostream {
    public:
        null_out_stream() : std::ostream (&buf) {}
    private:
        null_out_buf buf;
};

null_out_stream cnul;       // My null stream.

int main (void) {
    std::cout << std::boolalpha;

    //testing nul

    std::cout << "Nul stream before: " << cnul.fail() << std::endl;
    cnul << "Goodbye World!" << std::endl;
    std::cout << "Nul stream after: " << cnul.fail() << std::endl;
}
5 голосов
/ 19 октября 2011

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

В противном случае довольно просто реализовать нулевой поток;единственная функция streambuf, которую вы действительно должны переопределить, это overflow.Что-то вроде следующего должно сделать трюк:

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

(Буфер избегает некоторых ненужных вызовов виртуальных функций. На некоторых платформах это имеет существенное значение.)

Затем создайте выводstream, который его использует:

class NulOStream : public NulStreambuf, public std::ostream
{
public:
    NulOStream() : std::ostream( this ) {}
};

(Использование наследования, а не сдерживания гарантирует, что streambuf полностью создан перед передачей в ostream. На практике это обычно не требуется, нопохоже, что стандарт не разрешает передавать еще не сконструированный streambuf в конструктор ostream.)

2 голосов
/ 19 октября 2011

Самое простое решение: используйте std::stringstream.

#include <sstream>
#include <iostream>

void func(std::ostream& o){
    o << "blatest\n";
}

int main(){
    std::stringstream black_hole;
    func(std::cout);
    func(black_hole);
}

. stringstream будет содержать вывод, но если вы его не используете, он будет таким же, как если бы он никогда не был заполнен.

0 голосов
/ 21 апреля 2017

Так как никто не упомянул об этом, если речь идет о подавлении вывода std или ошибок, вы можете просто закрыть соответствующие файловые дескрипторы (например, fclose (stdout) или fclose (stderr)).
Это выдает все, включая такие вещи, как printf или fprintf (stderr, ...)
Таким образом, вы действительно будете продолжать использовать обычные cout или cerr, но они будут превращены в битовые сегменты.

0 голосов
/ 19 октября 2011

Некоторые предложения здесь http://bytes.com/topic/c/answers/589209-std-null-stream

Хороший ответ с этого сайта

Используйте обычный std :: fstream, открывайте его только для записи в нужный файл "/ DEV / нуль". Это должно работать.

Если вы действительно хотите создать собственный поток, просто извлеките его из basic_ostream и просто определите свой собственный оператор <<, чтобы быть функцией который возвращает только ссылку на поток. Вам придется написать пустышку Методы «write» и «put» (и все другие методы для вывода). </p>

На самом деле

#include <streambuf>
#include <ostream>

template <class cT, class traits = std::char_traits<cT> >
class basic_nullbuf: public std::basic_streambuf<cT, traits> {
typename traits::int_type overflow(typename traits::int_type c)
{
return traits::not_eof(c); // indicate success
}
};

template <class cT, class traits = std::char_traits<cT> >
class basic_onullstream: public std::basic_ostream<cT, traits> {
public:
basic_onullstream():
std::basic_ios<cT, traits>(&m_sbuf),
std::basic_ostream<cT, traits>(&m_sbuf)
{
init(&m_sbuf);
}

private:
basic_nullbuf<cT, traits> m_sbuf;
};

typedef basic_onullstream<char> onullstream;
typedef basic_onullstream<wchar_t> wonullstream;

С http://bytes.com/topic/c/answers/428285-null-ostream

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...