2009-11-02 12 views
11

क्या Eget पहले से ही पहुंचने पर भी fgets() हमेशा चार बफर को \ 0 के साथ समाप्त कर देता है? ऐसा लगता है कि यह करता है (यह निश्चित रूप से एएनएसआई के & आर पुस्तक में प्रस्तुत कार्यान्वयन में करता है), लेकिन मैंने सोचा कि मैं निश्चित रूप से पूछूंगा।क्या fgets() हमेशा चार बफर को 0 के साथ समाप्त कर देता है?

मुझे लगता है कि यह प्रश्न अन्य समान कार्यों जैसे कि हो जाता है()।

संपादित करें: मुझे पता है कि \ "सामान्य" परिस्थितियों में जोड़ा गया है, मेरा प्रश्न ईओएफ या त्रुटि शर्तों पर लक्षित है। उदाहरण के लिए:

FILE *fp; 
char b[128]; 
/* ... */ 
if (feof(fp)) { 
    /* is \0 appended after EACH of these calls? */ 
    fgets(b, 128, fp); 
    fgets(b, 128, fp); 
    fgets(b, 128, fp); 
} 
+1

हमेशा 'fgets की वापसी मान) की जांच (': 'अगर (fgets (...) == शून्य)/* अनिश्चित सरणी * /;' – pmg

+0

आप सही हो सकता है, तथापि, मैं देखता हूं कि '\ 0' हमेशा बताए गए अन्य उत्तरों हैं, भले ही' fgets() '' NULL 'लौटाए। – Ree

उत्तर

6

कभी भी उपयोग नहीं होता !!

 
    7.19.7.2 The fgets function 
    Synopsis 
1   #include <stdio.h> 
      char *fgets(char * restrict s, int n, 
       FILE * restrict stream); 
    Description 
2 The fgets function reads at most one less than the number of characters 
    specified by n from the stream pointed to by stream into the array pointed 
    to by s. No additional characters are read after a new-line character 
    (which is retained) or after end-of-file. A null character is written 
    immediately after the last character read into the array. 
    Returns 
3 The fgets function returns s if successful. If end-of-file is encountered 
    and no characters have been read into the array, the contents of the array 
    remain unchanged and a null pointer is returned. If a read error occurs 
    during the operation, the array contents are indeterminate and a null 
    pointer is returned. 

तो, हाँ, जब fgets() शून्य गंतव्य सरणी वापस नहीं करता है हमेशा एक अशक्त चरित्र है।

यदि fgets() शून्य लौटाता है, तो गंतव्य सरणी बदल दी गई हो सकती है और इसमें कोई शून्य चरित्र नहीं हो सकता है। fgets() से न्यूल प्राप्त करने के बाद कभी भी सरणी पर भरोसा न करें।


संपादित उदाहरण

 
$ cat fgets_error.c 
#include <stdio.h> 

void print_buf(char *buf, size_t len) { 
    int k; 
    printf("%02X", buf[0]); 
    for (k=1; k<len; k++) printf(" %02X", buf[k]); 
} 

int main(void) { 
    char buf[3] = {1, 1, 1}; 
    char *r; 

    printf("Enter CTRL+D: "); 
    fflush(stdout); 
    r = fgets(buf, sizeof buf, stdin); 
    printf("\nfgets returned %p, buf has [", (void*)r); 
    print_buf(buf, sizeof buf); 
    printf("]\n"); 

    return 0; 
} 
$ ./a.out 
Enter CTRL+D: 
fgets returned (nil), buf has [01 01 01] 
$ 

देखें जोड़ा?buf में कोई एनयूएल नहीं :)

+0

आप जीतते हैं: डी .... – Ree

+0

@pmg फिर "कभी भी उपयोग नहीं होता !!", क्या आपके पास फ़ाइल पढ़ने के लिए एक विकल्प है? – atlex2

+1

@ atlex2: हाँ, विकल्प 'fgets() 'है। – pmg

0

हां यह करता है। CPlusPlus.com से

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

एक न्यूलाइन चरित्र fgets पढ़ने को रोकता है, लेकिन इसे एक वैध चरित्र माना जाता है और इसलिए इसे स्ट्रिंग में स्ट्रिंग में शामिल किया गया है।

सी स्ट्रिंग के अंत को सिग्नल करने के लिए वर्णों को पढ़ने के बाद एक शून्य वर्ण स्वचालित रूप से स्ट्र में जोड़ा जाता है।

7

fgets हमेशा इस वजह से पढ़ने के बफर करने के लिए एक '\ 0' जोड़ने करता है, यह धारा से ज्यादा से ज्यादा size - 1 पात्रों पढ़ता (size दूसरा पैरामीटर रहा है)।

कभी भी gets का उपयोग न करें क्योंकि आप कभी भी गारंटी नहीं दे सकते कि यह आपके द्वारा दिए जाने वाले किसी भी बफर को ओवरफ़्लो नहीं करेगा, इसलिए तकनीकी रूप से यह हमेशा पढ़ने वाली स्ट्रिंग को समाप्त करता है, यह वास्तव में मदद नहीं करता है।

2

आदमी fgets:

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

0

यदि आपने बाइनरी मोड "आरबी" में फ़ाइल खोल दी है, और यदि आप fgets का उपयोग कर लाइन द्वारा टेक्स्ट लाइन को पढ़ना चाहते हैं तो आप अपने कोड को खोने के अपने सॉफ़्टवेयर की सुरक्षा के लिए निम्न कोड का उपयोग कर सकते हैं, अगर किसी गलती से पाठ में '\ 0' बाइट होता है। लेकिन अंत में उल्लिखित अन्य लोगों की तरह, आमतौर पर आपको fgets का उपयोग नहीं करना चाहिए यदि स्ट्रीम में '\ 0' है।


size_t filepos=ftell(stream); 
fgets(buffer, buffersize, stream); 
len=strlen(buffer); 
/* now check for > len+1 since no problem if the 
    last byte is 0 */ 
if(ftell(stream)-filepos > len+1) 
{ 
    if(!len) filepos++; 
    if(!fseek(stream, filepos, SEEK_SET) && len) 
    { 
     fread(buffer, 1, len, stream); 
     buffer[len]='\0'; 
    } 
} 
संबंधित मुद्दे