निचला-रेखा शीर्ष: श्वेत-स्थान की उचित हैंडलिंग के साथ, निम्नलिखित है कि कैसे eof
इस्तेमाल किया जा सकता है (और यहां तक कि, fail()
जाँच की तुलना में अधिक विश्वसनीय हो ):
while( !(in>>std::ws).eof() ) {
int data;
in >> data;
if ( in.fail() ) /* handle with break or throw */;
// now use data
}
( जवाब को उजागर करने के सुझाव के लिए टोनी डी का धन्यवाद। उदाहरण के लिए उनकी टिप्पणी नीचे देखें कि यह अधिक मजबूत क्यों है। )
उपयोग eof()
करने के खिलाफ मुख्य तर्क सफेद स्थान की भूमिका के बारे में एक महत्वपूर्ण सूक्ष्मता याद आ रही है। मेरा प्रस्ताव यह है कि, eof()
स्पष्ट रूप से जाँच करना न केवल " हमेशा गलत " है - जो कि इस और इसी तरह के थ्रेड्स में एक ओवरराइडिंग राय लगती है - लेकिन सफेद-अंतरिक्ष के उचित संचालन के साथ, यह एक क्लीनर और अधिक विश्वसनीय प्रदान करता है। त्रुटि से निपटने, और हमेशा सही समाधान है (हालांकि, जरूरी नहीं कि सबसे कठिन)।
संक्षेप में "उचित" समाप्ति और पठन आदेश के रूप में जो सुझाव दिया जा रहा है, वह निम्नलिखित है:
int data;
while(in >> data) { /* ... */ }
// which is equivalent to
while( !(in >> data).fail() ) { /* ... */ }
ईओएफ से परे पढ़ने के प्रयास के कारण विफलता को समाप्ति की स्थिति के रूप में लिया जाता है। इसका मतलब यह है कि एक सफल स्ट्रीम और एक के बीच अंतर करने का कोई आसान तरीका नहीं है जो वास्तव में ईओएफ के अलावा अन्य कारणों से विफल हो जाता है। निम्नलिखित धाराएँ लें:
1 2 3 4 5<eof>
1 2 a 3 4 5<eof>
a<eof>
while(in>>data)
एक सेट के साथ समाप्त हो जाता है failbit
के लिए सभी तीन इनपुट। पहले और तीसरे eofbit
में भी सेट किया गया है। इसलिए पिछले लूप से एक अनुचित इनपुट (1) को अनुचित लोगों (2 और 3) से अलग करने के लिए बहुत बदसूरत अतिरिक्त तर्क की आवश्यकता होती है।
जबकि, निम्नलिखित लें:
while( !in.eof() )
{
int data;
in >> data;
if ( in.fail() ) /* handle with break or throw */;
// now use data
}
यहां, यह in.fail()
सत्यापित करता है कि जब तक कुछ पढ़ने के लिए है, यह सही है। इसका उद्देश्य केवल लूप टर्मिनेटर नहीं है।
अब तक बहुत अच्छा है, लेकिन क्या होता है यदि धारा में जगह खाली होती है - eof()
टर्मिनेटर के रूप में प्रमुख चिंता की बात क्या है ?
हमें अपनी त्रुटि से निपटने के लिए आत्मसमर्पण करने की आवश्यकता नहीं है; बस सफेद अंतरिक्ष खाओ:
while( !in.eof() )
{
int data;
in >> data >> ws; // eat whitespace with std::ws
if ( in.fail() ) /* handle with break or throw */;
// now use data
}
std::ws
किसी भी संभावित (शून्य या अधिक) को स्थान पर छोड़ते समय स्ट्रीम में जगह छोड़ देता है eofbit
, और नहींfailbit
। इसलिए, in.fail()
अपेक्षित रूप से काम करता है, जब तक कि पढ़ने के लिए कम से कम एक डेटा न हो। यदि सभी-रिक्त धाराएँ भी स्वीकार्य हैं, तो सही रूप है:
while( !(in>>ws).eof() )
{
int data;
in >> data;
if ( in.fail() ) /* handle with break or throw */;
/* this will never fire if the eof is reached cleanly */
// now use data
}
सारांश: एक ठीक से निर्मित while(!eof)
न केवल संभव है और गलत नहीं है, लेकिन डेटा को दायरे में स्थानीयकृत करने की अनुमति देता है, और हमेशा की तरह व्यवसाय से त्रुटि की जाँच के क्लीनर जुदाई प्रदान करता है। यह कहा जा रहा है, while(!fail)
inarguably एक अधिक सामान्य और प्रतिकूल मुहावरा है, और सरल (एकल डेटा प्रति पाठ प्रकार) परिदृश्यों में पसंद किया जा सकता है।
scanf(...) != EOF
C में भी काम नहीं करेगा, क्योंकिscanf
खेतों की संख्या सफलतापूर्वक पार्स और असाइन की गई है। सही स्थिति वह हैscanf(...) < n
जहाँn
प्रारूप स्ट्रिंग में फ़ील्ड्स की संख्या है।