Ifstream.eof () फ़ाइल की अंतिम पंक्ति पढ़ने के बाद TRUE क्यों नहीं लौटाता है?


11

जब एक शुरुआत ifstreams पढ़ना बंद कर देती है, तो उसकी / उसकी वृत्ति एक लूप का उपयोग करके फ़ाइल को पढ़ने के लिए होती है जो आमतौर पर इस तरह दिखाई देती है:

while (!ifstream.eof()
{
...
}

हालाँकि, जब मैंने इस कोड का उपयोग किया तो मैंने देखा कि यह तब तक नहीं रुका जब तक यह फाइल की अंतिम पंक्ति को दो बार नहीं पढ़ गया। सी ++ प्रोग्रामर ध्यान दें कि यह वास्तव में नहीं है कि किसी को एक फ़ाइल को कैसे पढ़ना चाहिए। इसके बजाय, वे आमतौर पर सलाह देते हैं कि जिस किसी को फ़ाइल पढ़ने की आवश्यकता है, वह इसके बजाय लूप का उपयोग करता है:

while (ifstream >> someVar)
{
...
}

कोड का पहला टुकड़ा हमेशा ठीक से काम करने में विफल क्यों होता है?


मैंने सोचा होगा कि कोई डुप्लिकेट होगा, लेकिन मैं यहां एक नहीं ढूंढ सकता। स्टैकओवरफ़्लो पर बहुत सारे डुप्लिकेट हैं।
डेविड हैमेन

जवाबों:


4

while (!ifstream.eof())पाश क्योंकि धाराओं / C और C ++ में फ़ाइलों को जब आप फ़ाइल के अंत तक पहुँच चुके हैं, बल्कि संकेत मिलता है अगर आप को पढ़ने के लिए कोशिश की है की भविष्यवाणी नहीं है, काम नहीं करता है पिछले फ़ाइल के अंत।

यदि फ़ाइल की अंतिम पंक्ति एक नई पंक्ति ( \n) वर्ण के साथ समाप्त होती है , तो अधिकांश रीड एक्शन तब पढ़ना बंद कर देगा जब उन्होंने उस चरित्र का सामना किया हो और वे यह नहीं पता लगाते हैं कि यह फ़ाइल का अंतिम चरित्र है। अगली रीड एक्शन पर, यह भी हो सकता है कि अधिक वर्णों को जोड़ दिया गया है और यह कि रीड उन्हें निकालने में सफल होगा।

स्ट्रीम निष्कर्षण ऑपरेटर ( while (ifstream >> someVar)) का उपयोग करते हुए लूप काम करता है क्योंकि स्ट्रीम निष्कर्षण ऑपरेटर से परिणाम गलत का मूल्यांकन करता है यदि यह सही प्रकार का आइटम नहीं निकाल सकता है। ऐसा तब भी होता है जब पढ़ने के लिए कोई पात्र नहीं बचा है।


4

हालाँकि, C ++ प्रोग्रामर ध्यान दें कि हमेशा ऐसा होता है कि Cin.eof () अंतिम पंक्ति को दो बार पढ़ने के बाद "सही" वापस नहीं करता है।

जो हो रहा है, वह नहीं है। eofbitबूलियन के लिए रूपांतरण में एक भूमिका निभाता ( stream::operator bool(या operator void*पुराने C ++))। केवल badbitऔर failbitशामिल हैं।

मान लीजिए आप एक फाइल पढ़ रहे हैं जिसमें व्हाट्सएप द्वारा अलग किए गए नंबर हैं। चारों ओर आधारित एक लूप cin.eof()अनिवार्य रूप से गलत होगा या ifपरीक्षणों से भरा होगा । आप EOF तक नहीं पढ़ रहे हैं। आप नंबर पढ़ रहे हैं। तो अपने कोड को उस तर्क को व्यक्त करें:

while (stream >> some_var) {
    process_value(some_var);
}

यह काम करेगा कि फ़ाइल की अंतिम पंक्ति के साथ 0 42\nया बस समाप्त होती है 0 42(फ़ाइल में अंतिम पंक्ति के अंत में कोई नई पंक्ति नहीं)। यदि फ़ाइल के साथ समाप्त होता है 0 42\n, तो अंतिम अच्छा पढ़ा गया मान 42 मान लेगा और लाइन मार्कर के अंतिम छोर को पढ़ेगा। ध्यान दें कि ईओएफ मार्कर अभी तक पढ़ा नहीं गया है। फ़ंक्शन के process_valueसाथ कहा जाता है 42। धारा निष्कर्षण ऑपरेटर >> के बगल में कॉल EOF पढ़ता है, और कुछ भी नहीं है के बाद से निकाला गया है, दोनों eofbitऔर failbitस्थापित किया जाएगा।

दूसरी ओर, मान लीजिए कि फ़ाइल समाप्त होती है 0 42(अंतिम पंक्ति के अंत में कोई नई पंक्ति नहीं)। अंतिम अच्छा पढ़ा हुआ ईओएफ मार्कर पर मूल्य 42 को समाप्त कर देगा। संभवतः आप उस 42 को संसाधित करना चाहते हैं। यही कारण है कि eofbitइनपुट स्ट्रीम बूलियन रूपांतरण ऑपरेटर में कोई भूमिका नहीं निभाता है। स्ट्रीम निष्कर्षण ऑपरेटर >> के लिए अगले कॉल पर, अंतर्निहित मशीनरी जल्दी से देखती है कि eofbitयह पहले से ही सेट है। यह जल्दी से स्थापित करने में परिणाम है failbit

कोड का पहला टुकड़ा हमेशा ठीक से काम करने में विफल क्यों होता है?

क्योंकि आपको लूप स्थिति के रूप में ईओएफ के लिए जाँच नहीं करनी चाहिए। लूप स्थिति को व्यक्त करना चाहिए कि आप क्या करने की कोशिश कर रहे हैं, जो (उदाहरण के लिए) है, एक धारा से संख्याओं को निकालना।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.