istreambuf_iterator
और istream_iterator
के बीच क्या अंतर है? और सामान्य रूप से धाराओं और स्ट्रीमबफ के बीच क्या अंतर है? मुझे वास्तव में इसके लिए कोई स्पष्ट स्पष्टीकरण नहीं मिल रहा है इसलिए यहां पूछने का फैसला किया गया।सी ++ स्ट्रीम भ्रम: istreambuf_iterator बनाम istream_iterator?
उत्तर
IOstreams स्ट्रीमबफ का उपयोग उनके स्रोत/इनपुट/आउटपुट के लक्ष्य के रूप में करते हैं। प्रभावी रूप से, स्ट्रीमबफ-फ़ैमिली आईओ और आईओस्ट्रीम-फ़ैमिली के संबंध में सभी काम करता है केवल फ़ॉर्मेटिंग और टू-स्ट्रिंग/स्ट्रिंग ट्रांसफॉर्मेशन के लिए उपयोग किया जाता है।
अब, istream_iterator
एक टेम्पलेट तर्क का कहना है कि क्या streambuf से अस्वरूपित स्ट्रिंग-अनुक्रम int
रों के रूप में (सफेद स्थान को परिसीमित), के रूप में स्वरूपित किया जाना चाहिए istream_iterator<int>
तरह की व्याख्या करेगा सभी आने वाली पाठ लेता है।
दूसरी ओर, istreambuf_iterator
केवल कच्चे पात्रों की परवाह करता है और सीधे istream
के संबंधित स्ट्रीमबफ पर इसे फिर से चलाता है।
आम तौर पर, यदि आप केवल कच्चे पात्रों में रुचि रखते हैं, तो istreambuf_iterator
का उपयोग करें। यदि आप स्वरूपित इनपुट में रूचि रखते हैं, तो istream_iterator
का उपयोग करें।
मैंने जो कुछ भी कहा वह भी ostream_iterator
और ostreambuf_iterator
पर लागू होता है।
यहां वास्तव में एक बुरी तरह से गुप्त रहस्य है: एक iostream प्रति से, वास्तव में आपके कंप्यूटर पर फ़ाइल से पढ़ने/लिखने के लिए लगभग कुछ भी नहीं है।
एक iostream मूल रूप से एक streambuf और एक स्थान के बीच एक "मैचमेकर" के रूप में कार्य करता है:
iostream दुकानों को रूपांतरण के एक के लिए (जैसे, वर्तमान चौड़ाई और सटीक किया जाना चाहिए के बारे में कुछ राज्य रूपांतरण)। यह लोकेल को निर्देशित करने के लिए उन लोगों का उपयोग करता है कि रूपांतरण कैसे करें और कहां करें (उदा।, इस संख्या को चौड़ाई 8 और परिशुद्धता 5 के साथ उस बफर में एक स्ट्रिंग में कनवर्ट करें)।
हालांकि आपने इसके बारे में सीधे नहीं पूछा था, इसके बदले में लोकेल वास्तव में केवल एक कंटेनर है - लेकिन (एक विषमता के लिए) एक प्रकार के विषम कंटेनर। इसमें शामिल चीजें facet
एस हैं। एक पहलू वस्तु एक समग्र लोकेल के एक पहलू को परिभाषित करता है। मानकों को पढ़ने और लिखने की संख्या (num_get
, num_put
) से पात्रों को वर्गीकृत करने के लिए मानक (सीटीपी पहलू) को वर्गीकृत करने के लिए मानक कई पहलुओं को परिभाषित करता है।
डिफ़ॉल्ट रूप से, एक स्ट्रीम "सी" लोकेल का उपयोग करेगी। यह बहुत बुनियादी है - संख्याओं को सिर्फ अंकों की धारा के रूप में परिवर्तित किया जाता है, केवल एक चीज जो इसे पहचानने के रूप में पहचानती है वह 26 निचले मामले और 26 ऊपरी केस अंग्रेजी अक्षरों और इसी तरह के होते हैं। हालांकि, आप imbue
अपनी पसंद के एक अलग लोकेल के साथ एक स्ट्रीम कर सकते हैं। आप तारों में निर्दिष्ट नामों से उपयोग करने के लिए लोकेशंस चुन सकते हैं। एक जो विशेष रूप से दिलचस्प है वह एक खाली स्ट्रिंग द्वारा चुना जाता है। रिक्त स्ट्रिंग का उपयोग मूल रूप से रनटाइम लाइब्रेरी को उस लोकेल का चयन करने के लिए बताता है, जो "सोचता है" सबसे उपयुक्त है, आमतौर पर उपयोगकर्ता ने ऑपरेटिंग सिस्टम को कैसे कॉन्फ़िगर किया है। यह किसी भी स्थानीय लोकेल के लिए स्पष्ट रूप से लिखे बिना स्थानीय प्रारूप में डेटा से डेटा को सौदा करने की अनुमति देता है।
तो, एक istream_iterator
और एक istreambuf_iterator
के बीच मूल अंतर यह है कि डेटा एक istreambuf_iterator से बाहर आने के स्थान के द्वारा किया परिवर्तनों (के सबसे) के माध्यम से नहीं गया है, लेकिन एक istream_iterator
से बाहर आने के डेटा तब्दील हो गया है लोकेल द्वारा।
क्या इसके लायक है के लिए, कि पिछले पैराग्राफ में तथ्य की बात कर रहा है "का सबसे" है कि जब आप डेटा एक istreambuf से (पुनरावर्तक के माध्यम से या अन्यथा) को पढ़ने के स्थान के आधार पर परिवर्तन का एक छोटा सा है किया गया: विभिन्न "स्वरूपण" प्रकारों के साथ, लोकेल में एक कोडेकैट पहलू होता है, जिसका उपयोग किसी बाहरी प्रतिनिधित्व से कुछ आंतरिक प्रतिनिधित्व में परिवर्तित करने के लिए किया जाता है (उदाहरण के लिए, यूटीएफ -8 से यूटीएफ -32)।
यह अधिक अर्थपूर्ण हो सकता है इस तथ्य की अनदेखी है कि वे दोनों एक स्थान में संग्रहीत किया जाता है, और केवल शामिल व्यक्ति पहलुओं के बारे में सोच रहे हैं:
ताकि बीच वास्तविक अंतर होता है istream_iterator
और एक istreambuf_iterator
। परिवर्तन का थोड़ा सा हिस्सा (कम से कम संभावित रूप से) डेटा से किया जाता है, लेकिन कमistreambuf_iterator
से आने वाले डेटा के लिए किया जाता है।
अच्छी व्याख्या। सीधे कच्चे बाइनरी डेटा के लिए Streambufs का उपयोग करने के बारे में क्या, यह संभव है? – Pavel
@ पावेल: ऐसा नहीं है कि सी ++ की आईस्ट्रीम कैसे काम करती है, लेकिन कम से कम सिद्धांत में, ऐसा कोई कारण नहीं है कि वे नहीं कर सके। मुझे संदेह है कि आप हालांकि करना चाहते हैं - अगर आपने किया, तो आपको एक समय में 'कोडेकवीटी' रूपांतरण एक चरित्र लागू करना होगा, क्योंकि आप कच्चे बफर से डेटा पढ़ते हैं, जो मुझे लगता है कि आम तौर पर एक मेला खो देता है गति की मात्रा (एक समय में एक पूरे बफर को बदलने की तुलना में)। –
यही कारण है कि मैं iostreams का उपयोग नहीं करना चाहता क्योंकि मैं नहीं चाहता कि codecvt शामिल है। – Pavel
"आम तौर पर, यदि आप केवल कच्चे पात्रों में रुचि रखते हैं, तो एक istream_iterator का उपयोग करें" - क्या यह 'istreambuf_iterator' होना चाहिए? – Mankarse
@ मंकर्स: एर्म, ज़ाहिर है, धन्यवाद। – Xeo
इससे मेरे लिए यह और अधिक स्पष्ट हो गया, धन्यवाद! – dextrey