2009-06-24 17 views
15

मैंने हाल ही में fstream :: eof() का उपयोग करके एक समस्या में भाग लिया। मैंने here से निम्नलिखित पंक्ति पढ़ी:std :: fstream ने EOF बिट को जिस तरह से सेट किया है?

फ़ंक्शन eof() संबंधित इनपुट फ़ाइल का अंत तक पहुंच गया है, तो गलत साबित होता है, अन्यथा झूठा।

और (गलती से) मान लिया गया कि इसका मतलब यह हुआ कि अगर मैंने fstream :: read() का उपयोग किया और फ़ाइल के अंत में पढ़ा, तो फ़ंक्शन eof() मुझे बताएगा।

for(int i = 0; i < max && !file.eof(); i++) 
{ 
    file.read(mything, sizeof(mything)); 
} 

समस्या क्योंकि जो बाद में ऊपर लिंक पृष्ठ पर समझाया गया है की आया था (मैं शुरू में पढ़ने में विफल, भ्रामक पहले पैराग्राफ के लिए धन्यवाद):

तो मैं कुछ इस तरह (बहुत सामान्यीकृत) किया

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

तो मैंने बदल दिया, और अब मेरा लूप file.eof() के बजाय file.fail() के खिलाफ जांचता है, और मैं समझता हूं कि कैसे eof() काम करता है। मेरा सवाल है, यह इस तरह क्यों काम करता है? क्या ऐसी स्थितियां हैं जहां यह वांछनीय है? ऐसा लगता है कि एक बार जब आप ईओएफ पास कर चुके हैं, तो आपने ईओएफ पास कर दिया है और ईओएफ() को सच होना चाहिए।

अद्यतन प्रतिक्रिया के लिए धन्यवाद, मैं मुझे मिल गया लगता है। एकमात्र ऑपरेशन जो मैं कर रहा हूं वह पढ़ा जाता है(), और मैं तुरंत असफल() की जांच करता हूं, इसलिए मुझे लगता है कि मैं ठीक हूं। अब, मेरा सवाल है, मैं eof() के लिए उपयोग करता हूं?

+1

(int i = 0; i

उत्तर

15

क्योंकि इस तरह यह फ़ाइल को कितनी बड़ी जानकारी के बिना EOF का पता लगा सकता है। इसे बस इतना करना है कि पढ़ने का प्रयास करें और यदि पढ़ा छोटा है (लेकिन कोई त्रुटि नहीं है), तो आप फ़ाइल के अंत तक पहुंच गए हैं।

यह read सिस्टम कॉल की कार्यक्षमता को प्रतिबिंबित करता है, जो फ़ाइल IO आमतौर पर कॉलिंग समाप्त होता है (Win32 सामान ReadFile पर कॉल कर सकता है लेकिन मुझे विश्वास है कि कार्यक्षमता समान है)।

read मैनपेज "वापसी मान" अनुभाग से (जोर जोड़ा):

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

Btw: लिखने के लिए एक अच्छा तरीका है कि इस प्रकार होगा चाहता था:

T something; 
while(file.read(something, sizeof(something))) { 
    // process your 'something' 
} 

इस काम करता है क्योंकि file.read (iostream के कई सदस्यों की तरह) iostream खुद के लिए एक संदर्भ लौट आते हैं। स्ट्रीम राज्य की जांच करने की अनुमति देने के लिए जिनमें से सभी ऑपरेटर ओवरलोड हो गए हैं। इसी तरह std::cin से पढ़ने के लिए, while(std::cin >> x) { ... } भी काम करता है।

संपादित करें: आपको पता होना चाहिए कि परीक्षण बनाम असफल उसी कारण से समान रूप से गलत हो सकता है। fail() से जुड़े पृष्ठ से पिछले ऑपरेशन विफल हो गया है। जिसका अर्थ है कि आपको इसका परीक्षण करने से पहले एक पठन या अन्य प्रासंगिक संचालन करने की आवश्यकता है।

0
int n; 
std::cin >> n >> std::stripws; 

इस समस्या को हल करता है। उस बिंदु पर आप या तो .good() या .eof() का उपयोग कर सकते हैं। मुझे .good() का उपयोग करना पसंद है, क्योंकि यदि कोई खराब डिस्क ब्लॉक है, तो .good() इसका पता लगाएगा। लेकिन वह मैं हूँ। .eof() नहीं होगा, आपको भी .fail() || जोड़ना होगा ।खराब()।

मुझे व्हाइटस्पेस खाने की समस्या के बारे में कुछ कठिन अध्ययन के बाद यह पता चला। मैं iostream और ifstream के लिए एक ईसीओ प्रस्तावित करने जा रहा था, और देखो और देखो, यह पहले से ही किया जा चुका है। :- डी

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