सी

2012-09-09 5 views
9

में कैसे feof() काम करता है क्या feof() फाइलपोइंटर की वर्तमान स्थिति के लिए eof के लिए जांचता है या वर्तमान फ़ाइल पॉइंटर के बगल में स्थित स्थिति के लिए जांच करता है?सी

आपकी मदद के लिए धन्यवाद!

उत्तर

27

प्रत्येक FILE स्ट्रीम में एक आंतरिक ध्वज है जो इंगित करता है कि कॉलर ने पहले से ही फ़ाइल के अंत को पढ़ने की कोशिश की है या नहीं। feof उस ध्वज को लौटाता है। ध्वज यह इंगित नहीं करता है कि वर्तमान फ़ाइल स्थिति फ़ाइल के अंत के रूप में है या नहीं, केवल पिछले पढ़ने के लिए फ़ाइल के अंत में पढ़ने की कोशिश की गई है या नहीं।

उदाहरण के तौर पर, दो बाइट वाली फ़ाइल के माध्यम से पढ़ने पर, क्या होता है, इसके माध्यम से चलते हैं।

f = fopen(filename, "r"); // file is opened 
assert(!feof(f));   // eof flag is not set 
c1 = getc(f);    // read first byte, one byte remaining 
assert(!feof(f));   // eof flag is not set 
c2 = getc(f);    // read second byte, no bytes remaining 
assert(!feof(f));   // eof flag is not set 
c3 = getc(f);    // try to read past end of the file 
assert(feof(f));   // now, eof flag is set 

यही कारण है कि निम्नलिखित गलत तरह से जब एक फ़ाइल के माध्यम से पढ़ने EOF उपयोग करने के लिए है:

f = fopen(filename, "r"); 
while (!feof(f)) { 
    c = getc(f); 
    putchar(c); 
} 
जिस तरह से काम करता है के feof

, अंत फ़ाइल झंडा ही है एक बार सेट करें getc फ़ाइल के अंत में पढ़ने की कोशिश करता है। getc फिर EOF लौटाएगा, जो एक चरित्र नहीं है, और लूप निर्माण putchar को लिखने का प्रयास करने के कारण होता है, जिसके परिणामस्वरूप त्रुटि या कचरा आउटपुट होता है। getc विशेष मूल्य EOF रिटर्न अगर यह पिछले फ़ाइल के अंत पढ़ने के लिए करने की कोशिश की, या पढ़ते समय यदि कोई त्रुटि थी:

हर सी मानक पुस्तकालय इनपुट विधि की सफलता या विफलता का एक संकेत देता है। विशेष मूल्य अंत-फ़ाइल और त्रुटि के लिए समान है, और यह वह जगह है जहां feof का उपयोग करने का उचित तरीका निम्न में आता है: आप इसका उपयोग अंत-फ़ाइल और त्रुटि स्थितियों के बीच अंतर करने के लिए कर सकते हैं। ferror:

f = fopen(filename, "r"); 
c = getc(f); 
if (c == EOF) { 
    if (feof(f)) 
     printf("it was end-of-file\n"); 
    else 
     printf("it was error\n"); 
} 

त्रुटि स्थितियों के लिए FILE वस्तुओं के लिए एक और आंतरिक झंडा नहीं है। "फ़ाइल के अंत नहीं" की बजाय त्रुटियों के परीक्षण के लिए अक्सर स्पष्ट होता है। सी में एक फ़ाइल के माध्यम से पढ़ने के लिए एक मुहावरेदार तरह से इस तरह है:

f = fopen(filename, "r"); 
while ((c = getc(f)) != EOF) { 
    putchar(c); 
} 
if (ferror(f)) { 
    perror(filename): 
    exit(EXIT_FAILURE); 
} 
fclose(f); 

(कुछ त्रुटि जाँच यहाँ उदाहरण से elided किया गया है, संक्षिप्तता के लिए।)

feof समारोह काफी मुश्किल से ही उपयोगी है।

+2

सरल और सही :-) – cnicutar

+1

क्षमा करें, उत्साहित हो गया और इसे थोड़ा बढ़ाया। –

+0

यह भी बेहतर है – cnicutar

3

आप यह समझकर कि feof कैसे काम करता है, यह बेहतर तरीके से समझ सकते हैं कि यह कैसे कार्यान्वित किया जाता है। 7 वीं संस्करण यूनिक्स stdio लाइब्रेरी feof लागू करने का एक सरल संस्करण यहां दिया गया है। आधुनिक पुस्तकालय बहुत समान हैं, थ्रेड-सुरक्षा, बढ़ी हुई दक्षता और क्लीनर कार्यान्वयन की पेशकश कोड जोड़ना।

extern struct _iobuf { 
    char *_ptr; 
    int  _cnt; 
    char *_base; 
    char _flag; 
    char _file; 
} _iob[_NFILE]; 

#define _IOEOF 020 

#define feof(p)   (((p)->_flag&_IOEOF)!=0) 

#define getc(p)   (--(p)->_cnt>=0? *(p)->_ptr++&0377:_filbuf(p)) 

int 
_filbuf(FILE *iop) 
{ 

    iop->_ptr = iop->_base; 
    iop->_cnt = read(fileno(iop), iop->_ptr, BUFSIZ); 
    if (iop->_cnt == 0) { 
      iop->_flag |= _IOEOF; 
      return(EOF); 
    } 
    return(*iop->_ptr++ & 0377); 

}

stdio पुस्तकालय प्रत्येक फ़ाइल के साथ एक संरचना _base द्वारा बताया एक आंतरिक बफर युक्त बनाए रखता है।बफर में वर्तमान वर्ण _ptr द्वारा इंगित किया गया है और उपलब्ध वर्णों की संख्या _cnt में निहित है। getc मैक्रो, जो उच्च स्तर की कार्यक्षमता के लिए आधार है, जैसे scanf, बफर से एक चरित्र को वापस करने का प्रयास करता है। यदि बफर खाली है, तो इसे भरने के लिए _filbuf पर कॉल किया जाएगा। बदले में _filbufread पर कॉल करेगा। यदि read 0 देता है, जिसका अर्थ है कि कोई और डेटा उपलब्ध नहीं है, _filbuf_IOEOF ध्वज सेट करेगा, जो feof प्रत्येक बार जब आप इसे सही करने के लिए कहते हैं तो चेक करता है।

जैसा कि आप उपर्युक्त से समझ सकते हैं, feof पहली बार जब आप फ़ाइल के अंत (या लाइब्रेरी फ़ंक्शन आपकी तरफ से प्रयास करता है) के चरित्र को पढ़ने का प्रयास करते हैं तो यह सच हो जाएगा। इसने विभिन्न कार्यों के व्यवहार पर सूक्ष्म प्रभाव डाले हैं। एक वर्ण वाली फ़ाइल पर विचार करें: अंक 1getc के साथ उस चरित्र को पढ़ने के बाद, feof झूठी वापसी करेगा, क्योंकि _IOEOF ध्वज अनसेट है; किसी ने अभी तक फ़ाइल के अंत को पढ़ने की कोशिश नहीं की है। getc पर कॉल करने के परिणामस्वरूप read पर कॉल किया जाएगा, _IOEOF ध्वज की सेटिंग, और इससे feof सही होने के लिए कारण होगा। हालांकि, fscanf("%d", &n) का उपयोग कर उसी फ़ाइल से संख्या पढ़ने के बाद, feof तुरंत वापस आ जाएगा, क्योंकि fscanf पूर्णांक के अतिरिक्त अंक पढ़ने की कोशिश करेगा।