2010-12-01 10 views
16

संभव डुप्लिकेट:
Why is iostream::eof inside a loop condition considered wrong?परीक्षण stream.good() या stream.eof() अंतिम पंक्ति पढ़ता दो बार

मैं कोड का निम्न भाग है:

ifstream f("x.txt"); 
string line; 
while (f.good()) { 
    getline(f, line); 
    // Use line here. 
} 

लेकिन यह अंतिम पंक्ति को दो बार पढ़ता है। ऐसा क्यों होता है और मैं इसे कैसे ठीक करूं? बहुत समान

कुछ होता है के साथ:

ifstream f("x.txt"); 
string line; 
while (!f.eof()) { 
    getline(f, line); 
    // Use line here. 
} 
+1

यह एक डुप्लिकेट कैसा है? दूसरे उत्तर में परीक्षण के रूप में अच्छे() फ़ंक्शन के साथ लूपिंग का उल्लेख भी नहीं किया गया है। –

उत्तर

30

आप बहुत ही कम, बुरे, ईओफ़ और अच्छे की जांच करना चाहते हैं। विशेष रूप से eof के लिए (as! Stream.eof() एक आम गलती है), वर्तमान में ईओएफ में मौजूद धारा का मतलब यह नहीं है कि अंतिम इनपुट ऑपरेशन विफल हो गया है; इसके विपरीत, ईओएफ में नहीं होने का मतलब यह नहीं है कि अंतिम इनपुट सफल रहा था।

सभी स्ट्रीम स्टेट फ़ंक्शन - असफल, बुरे, ईफ, और अच्छे - भविष्य के संचालन की सफलता की भविष्यवाणी करने के बजाय आपको स्ट्रीम की वर्तमान स्थिति बताएं। सभी लाइनों

if (getline(stream, line)) { 
    use(line); 
} 
else { 
    handle_error(); 
} 

if (stream >> foo >> bar) { 
    use(foo, bar); 
} 
else { 
    handle_error(); 
} 

if (!(stream >> foo)) { // operator! is overloaded for streams 
    throw SomeException(); 
} 
use(foo); 

पढ़ने के लिए और इस प्रक्रिया: धारा ही वांछित ऑपरेशन के बाद (जो एक औंधा असफल जांच के बराबर है) की जाँच करें

for (std::string line; getline(stream, line);) { 
    process(line); 
} 

चुभते, अच्छा() misnamed है और नहीं है धारा के परीक्षण के बराबर (जो उपर्युक्त उदाहरण करते हैं)।

+0

ईओफ़ की जांच करने का हिस्सा सही है, लेकिन स्ट्रीम को जांचने का सुझाव थोड़ा सा है। 'अच्छा()' का मतलब है कि कोई भी ईफिट, बैडबिट, या असफलता सेट नहीं है। 'असफल()' का मतलब है कि या तो खराब या विफलता सेट है। स्ट्रीम की जांच (या तो शून्य * अभिसरण, या ऑपरेटर का उपयोग कर!) असफल() सदस्य फ़ंक्शन को कॉल करने जैसा ही है। – KeithB

+2

@ किथब: आप देख सकते हैं कि मैंने "शायद ही कभी चेक किया जाना चाहिए" समूह से असफल रहा। एक असफल स्ट्रीम महत्वपूर्ण है, और स्ट्रीम की जांच करना लगभग बराबर असफल() के मुकाबले लगभग हमेशा सुविधाजनक है। गेटलाइन (स्ट्रीम, लाइन) की तुलना करें! गेटलाइन (स्ट्रीम, लाइन) .fail()। –

8

बस

ifstream f("x.txt"); 
while (getline(f, line)) { 
    // whatever 
} 

यह मुहावरेदार तरह से इस तरह के एक पाश लिखने के लिए इस्तेमाल करते हैं। मैं त्रुटि को पुन: उत्पन्न करने में सक्षम नहीं हूं (लिनक्स मशीन पर)।

+0

मुझे केवल यह पता चला है कि यह क्यों काम करता है: आखिरी सफल कॉल गेटलाइन() _might_ set ** eof **, अगर अंतिम पंक्ति में अंत में कोई नई लाइन नहीं है। ** असफल ** बिट केवल तभी सेट किया जाता है जब getline() के लिए असफल कॉल हो। तो हम ** eof ** पर लूप को समाप्त नहीं करना चाहते हैं, लेकिन हम इसे ** विफल ** पर समाप्त करना चाहते हैं। –

+0

एक और बात .. मैं थोड़ी देर कर रहा था (f.peek()! = ईओएफ) {...} '। मुझे लगता है कि यह सही है? लेकिन मैं भविष्य में आपके उत्तर का उपयोग करूंगा। –

1

यह अंतिम पंक्ति को दो बार नहीं पढ़ा, लेकिन जब यह ईओफ़ पर पहुंचने में पढ़ने में असफल रहा, तो आपकी स्ट्रिंग लाइन के पास पहले का मान था।

ऐसा इसलिए है क्योंकि एफ अब "अच्छा" नहीं है जब उसने ईओएफ पढ़ा है, जब यह इसे पढ़ने वाला नहीं है।

संबंधित मुद्दे