2011-11-23 28 views
38

मैं std::ostream कार्यान्वयन की तलाश में हूं जो /dev/null जैसा कार्य करता है। यह केवल उस चीज़ को अनदेखा कर देगा जो इसे स्ट्रीम किया गया है। क्या मानक पुस्तकालयों या बूस्ट में ऐसी चीज मौजूद है? या मुझे अपना खुद का रोल करना है?क्या सी ++ या पुस्तकालयों में एक शून्य std :: ostream कार्यान्वयन है?

#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 
+2

आप '/ dev/null' को' std :: ofstream' –

+3

में खोल सकते हैं कुछ पोर्टेबल, @Alexandre – paperjam

+0

मुझे पता चला (अन्यथा यह एक उत्तर होगा) http://stackoverflow.com/questions/ 313111/dev-null-in-windows में पर्याप्त मामलों को कवर करना चाहिए। –

उत्तर

18

यदि आपके पास बढ़ावा है, तो बूस्ट/आईस्ट्रीम/डिवाइस/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())); 
... 
+6

इसका उपयोग करते हुए सबसे अधिक परेशान पार्स के लिए देखें ... – paperjam

+1

@paperjam, क्या आप विस्तृत कर सकते हैं? –

+0

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

15

आप एक धारा पर badbit सेट करते हैं यह उत्पादन कुछ भी नहीं होगा। यह परिणामस्वरूप स्ट्रीम में एक त्रुटि स्थिति होगी, लेकिन अधिकांश आउटपुट यह जांच नहीं पाएंगे; सामान्य मुहावरे बंद होने के बाद चेक को अंत में छोड़ना है (जो इसे आपके द्वारा लिखे गए कोड में रखेगा, जहां आप जानते हैं कि स्ट्रीम अमान्य होना चाहिए)।

अन्यथा, यह बहुत सीधे आगे लागू करने के लिए है: सिर्फ एक streambuf जो एक छोटे से बफर शामिल बनाते हैं, और overflow (हमेशा लौटने सफलता) में यह सेट करता है। ध्यान दें कि यह अनपेक्षित फ़ाइल से धीमा हो जाएगा, हालांकि; विभिन्न >> ऑपरेटर अभी भी रूपांतरण के लिए होंगे (जो स्ट्रीम में त्रुटि स्थिति होने पर वे नहीं करते हैं)।

संपादित करें:

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 का पता गुजर।

+11

जाहिर है, यह एक वैश्विक चर को संशोधित कर रहा है ... –

+2

@MatthieuM। 'Std :: cout << std :: boolalpha' का उपयोग करना वैश्विक चर का एक संशोधन भी है। 'Std :: cout << कुछ भी 'का उपयोग करना। मैं तुम्हारी बात समझ में नहीं आता। – Notinlist

+0

यद्यपि आप एक सामान्य मामले में इसके बारे में सही हैं, वही कार्यक्रम के कुछ हिस्सों के बीच हितों की टक्कर है यदि उनमें से एक या दोनों 'std :: cout' की कॉन्फ़िगरेशन को बदलते हैं। लेकिन फिर यह विन्यास योग्य क्यों है? अगर मैं अतीत में था और मैं सी ++ डिजाइन करता, तो मैं आउटपुट स्ट्रीम से आउटपुट फ़िल्टरिंग अलग करता हूं, जैसे कि 'std :: out_filter; << std :: boolalpha << std :: whatever_option; std :: out_proxy (std :: cout, of) << "कुछ"; '। – Notinlist

19

सरल समाधान सिर्फ एक बंद std::ofstream उपयोग करने के लिए है

+0

क्या आप कोड प्रदान कर सकते हैं? – einpoklum

+1

मूल विचार (खुला 'std :: ऑफस्ट्रीम') वास्तव में अच्छा काम करता है। क्या यह विश्वसनीय/मानक अनुपालन है, और भविष्य में समस्याएं (अपवाद?) का कारण नहीं है? मैं प्रदर्शन के बारे में थोड़ा चिंतित हूं, लेकिन मुझे लगता है कि एकमात्र अपशिष्ट '<<' ऑपरेटरों को बुलाया जा रहा है, एक 'अगर' की जांच कर रहा है और लौट रहा है? –

3

मैं जानता हूँ कि यह बहुत पुरानी धागा है, लेकिन मैं किसी को जो बढ़ावा बिना एक ही समाधान और और सबसे तेजी से एक की तलाश में है में जोड़ने के लिए चाहते हैं।

मैं ऊपर तीन अलग-अलग प्रस्तावों और एक/dev/बातिल के लिए सीधे लेखन (इसलिए यह कर्नेल शामिल है।)

हैरानी की बात यह है कि ज्यादातर NullStream मत मिले सबसे खराब प्रदर्शन किया संयुक्त।

यहाँ 100000000 लेखन के लिए परिणाम हैं:

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

संपादित

सबसे तेजी से समाधान है - जहां हम badbit का उपयोग करें - एक नकारात्मक पक्ष यह है। यदि कार्यक्रम जांचता है कि आउटपुट सफलतापूर्वक लिखा गया है - और मुझे नहीं पता कि प्रोग्राम को ऐसा क्यों नहीं करना चाहिए - तो यह इस खराब सीमा के कारण विफल हो जाएगा। इसलिए, रनर अप - बोस्ट - विजेता है।