2011-11-23 14 views
38

Ben /dev/null gibi davranan bir std::ostream uygulanması için arıyorum. Sadece akan herhangi bir şeyi göz ardı ederdi. Standart kütüphanelerde veya Boost'da böyle bir şey var mı? Yoksa kendi başıma mı dönmeliyim?C++ veya kütüphanelerde boş bir std :: ostream uygulaması var mı?

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

Çıkışlar:

a 
c 
+2

'/ dev/null' öğesini' std :: ofdream'de açabilirsiniz –

+3

Taşınabilir bir şeye ihtiyacınız var, @Alexandre – paperjam

+0

Anladım (aksi halde bu bir cevap olurdu) http://stackoverflow.com/questions/ Ancak, 313111/dev-null-in-windows yeterli durumu kapsamalıdır. –

cevap

18

Eğer boost varsa, o boost/iostreams/cihazın/null.hpp bir boş ostream & istream uygulama mevcut var. bunun özü:

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

Bu gibi kullanıyorsanız, çoğu bozma ayrıntısına dikkat edin ... – paperjam

+1

@paperjam, lütfen detaylandırır mısınız? –

+0

@ user1229080 http://stackoverflow.com/questions/1424510/most-vexing-parse-why-doesnt-a-a-work – boycy

15

o çıkış şey olmaz. Bu akışında bir hata durumunda sonuçlanacaktır, ancak çoğu outputters onay bu olmaz; Her zamanki deyim (eğer akışı geçersiz olması gerektiğini biliyoruz yazdığın kodu içinde vereceğini) kapanmasından sonra, sonuna kadar çek bırakmaktır.

Aksi halde uygulamaya oldukça yalındır var: sadece küçük bir tampon içeren streambuf oluşturmak ve overflow (her zaman dönen başarı) o kurar. Ancak bunun, açılmamış dosyadan daha yavaş olacağını unutmayın; Çeşitli >> operatörleri olacak hala (akışı bir hata durumu varsa onlar yapmazsanız olan) dönüşüm tümüne.

DÜZENLEME:

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

O kullanan bu tampon örneği içerecek şekilde de istream veya ostream türetilmiş bir kolaylık sınıfı, temin etmek üzere olağan var. Bir şey satırları:

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

Ya da sadece kendisine arasında streambuf adresini geçen bir std::ostream kullanabilirsiniz.

+11

Açıkçası, bu küresel bir değişkeni değiştiriyor ... –

+2

@MatthieuM. 'Std :: cout << std :: boolalpha' kullanmak da global bir değişkeni değiştirmektir. Ayrıca std :: cout << bir şey 'kullanma. Ben senin amacını anlamıyorum. – Notinlist

+0

Genel olarak bu konuda haklı olmanıza rağmen, bir veya her ikisi de std :: cout 'yapılandırmasını değiştirirse, aynı programın bölümleri arasında bir çıkar çatışması vardır. Ama o zaman neden yapılandırılabilir? Eğer geçmişte olsaydım ve C++ tasarlarsam, çıktı filtresinden çıktı akışını, std :: out_filter; of std :: boolalpha << std :: whatever_option; std :: out_proxy (std :: cout, of) << "bir şey"; '. – Notinlist

19

basit çözüm sadece açılmamış std::ofstream kullanmaktır bir akışta badbit ayarlarsanız

+0

Kod sağlayabilir misiniz? – einpoklum

+1

Özgün fikir (açılmamış 'std :: ofstream') gerçekten harika çalışıyor. Güvenilir/standart uyumlu mu ve ileride sorunlara (istisnalar?) Neden olma ihtimali yok mu? Performans hakkında biraz endişeliyim, ama sanırım tek atık “<<” operatörleri çağrılıyor, bir tanesi “if” ve geri dönüyor mu? –

3

Bu çok eski iplik olduğunu biliyorum, ama ben boost olmadan aynı çözüm ve en hızlı biri için isteyen herkese bu eklemek istiyorum.

ben yukarıdaki üç farklı öneri ve/dev/null doğrudan bir yazma (o çekirdek içerir böylece.)

Şaşırtıcı en fazla oyu NullStream en kötü performansı birleştirdi.Biz badbit kullanmak - - bir dezavantajı vardır

İşte
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) 

test kodu

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

DÜZENLEME

en hızlı çözümdür:

İşte 100,000,000 yazma için sonuçlardır. Program, çıktıyı başarılı bir şekilde yazıp yazmadığını kontrol ederse ve programın neden bunu yapmaması gerektiğine dair bir fikrim yok - o zaman bu hatadan dolayı başarısız olacaktır. Bu nedenle, kazanan - bost - kazanan.

İlgili konular