2011-05-13 19 views
10

मैं सी प्रोग्रामिंग भाषा में एक साधारण फ़ाइल स्प्लिटर/विलय प्रोग्राम पर काम कर रहा हूं। समस्या यह है कि, किसी कारण से fopen शून्य लौटाता है, और इसके कारण, मेरा प्रोग्राम fwrite कथन पर क्रैश हो रहा है। मैं यह कैसे तय करुं?'फॉपेन' एक नल पॉइंटर क्यों लौटाता है?

int SplitFile(char* filename, char* output, size_t size) 
{ 
    char current_file_name[256]; 
    int file_count = 0, i = 0; 
    FILE *file = fopen(filename, "rb"); 
    printf("split %s into chunks of %d named\n", filename, size); 

    if (!file) 
     return E_BAD_SOURCE; 
    else 
    { 
     output = (char *) malloc(size * sizeof(char)); 
     if (output == NULL) 
      return E_NO_MEMORY; 
     else 
     { 
      int bytes_read = 0; 
      FILE *outFile; 
      do 
      { 
       bytes_read = fread(output, sizeof(char), size, file); 
       sprintf(current_file_name, "%s%04lu\n", "part", file_count++); 
       outFile = fopen (current_file_name, "wb"); // THIS RETURNS NULL 
       fwrite(output, sizeof(char), bytes_read, outFile); //CRASHES ON THIS LINE 
      } 
      while (bytes_read > 0) 
       ; 

      //fclose(outFile); 
     } 
    } 
    fclose(file); 
    printf("...\n"); 
    return 0; 
} 
+1

Snarky - फाइल खोली इससे पहले कि आप इसे करने के लिए लिखने की कोशिश की जाँच करें। असली जवाब यह है कि आपके पास शायद फ़ाइल सिस्टम अनुमतियां नहीं हैं या यह फ़ोल्डर पथ में है जो – EnabrenTane

+9

मौजूद नहीं है 'errno' में कौन सी त्रुटि संग्रहीत की जाती है? बस 'if (! Outfile) perror ("fopen") जोड़ें;' और लाइब्रेरी को बताएं कि यह क्यों विफल हुआ। :) – sarnold

+0

त्रुटि में मुझे फॉपेन मिल रहा है: अवैध तर्क – k787

उत्तर

9

उचित बात करने के लिए जाँच errno है जब fopen रिटर्न NULL:

यहाँ सी फ़ाइल है।

मुझे लगता है कि आपकी समस्या यह है कि आप फाइल सिस्टम में लिखने की कोशिश कर रहे हैं जो फ़ाइल नामों में \n की अनुमति नहीं देता है, लेकिन यह एक अनुमति समस्या भी हो सकती है।

+1

से संबंधित है, तो करने के लिए और अधिक उचित बात है जब फॉपेन वापस लौटाता है तो त्रुटि की जांच करें। आप शायद fwrite के बजाय fopen मतलब था। –

+0

जब मैं स्प्रिंटफ पर टिप्पणी करता हूं और ऐसा करता हूं; आउटफाइल = फॉपेन ("part000", "wb"); यह बढ़िया काम करता है। – k787

+0

@ विन्डोज़: ओह! धन्यवाद। – Gabe

0

पहले रन में लिखने के लिए वापस लौटा है?

मैंने देखा कि जब आप लिखने के लिए खुली फाइलें रखते हैं लेकिन उन्हें बंद नहीं करते हैं। fwrite के बाद fclose (outfile) जोड़ने के लिए

प्रयास करें:

outFile = fopen (current_file_name , "wb");  
fwrite(output, sizeof(char), bytes_read, outFile); 
fclose(outFile) 

यह संभव है आप और अधिक फ़ाइलों को खोलने के अपने ओएस की अनुमति देता है की तुलना में।

+0

हाँ मैंने एक ही चीज़ सोचा और फ़ाइलों को बंद कर दिया, लेकिन – k787

1

जैसा कि गेबे ने कहा था कि आपकी समस्या फाइलनाम में नई लाइन है जो विंडोज में अवैध है।

लेकिन आप जीएनयू कोर यूटिलिटीज से विभाजित क्यों नहीं करते हैं। यूनिसेज/लिनक्स पर डिफ़ॉल्ट रूप से स्थापित, विंडोज़ के लिए GnuWin32 project से डाउनलोड किया जा सकता है।

split --suffix-length=4 --numeric-suffixes --bytes=1M - part < filename 
5

कई कारण हैं fopenNULL सहित (लेकिन निश्चित रूप से करने के लिए सीमित नहीं है) लौट सकते हैं:

  • फ़ाइल
  • मौजूद नहीं है फ़ाइल जो ऐसा नहीं करता एक मोड में खोला है अन्य पहुंच
  • नेटवर्क
  • फ़ाइल मौजूद है, लेकिन आपके पास अनुमति नहीं है
  • आपके द्वारा दिए गए नाम के साथ एक फ़ाइल मौजूद है, लेकिन प्रक्रिया की वर्तमान निर्देशिका वह नहीं है जो आपने अपेक्षित की है, इसलिए सापेक्ष पथनाम फ़ाइल को ढूंढने और खोलने में विफल रहता है।

errno कोड में खोदने का तरीका यह जानने का तरीका है।

हालांकि, क्योंकि आप इस विशेष त्रुटि को हल करते हैं, इसका मतलब यह नहीं है कि आप fopen मान सकते हैं NULL कभी वापस नहीं आएगा। I/O संचालन से निपटने पर आपके कोड को विफलता की अपेक्षा करना पड़ता है। I/O संचालन की सफलता की भविष्यवाणी करना संभव नहीं है, और वे हमेशा असफल हो सकते हैं।

+0

काम नहीं कर रहा था अंतरिक्ष से बाहर निकलने के बारे में क्या? क्या यह न्यूल वापस नहीं करेगा? (मुझे पता है कि आपने कहा "मेरे प्रश्न तक सीमित नहीं है" – Nande

+0

@Nande: 'fopen()' जो एक नई फ़ाइल बनाता है पूर्ण डिस्क पर सफल हो सकता है या नहीं। यदि निर्देशिका को विस्तार करने की आवश्यकता नहीं है (और आप इनोड्स से बाहर नहीं हैं), तो यह सफल हो सकता है, लेकिन निम्नलिखित 'fwrite() '(** या **' fclose() '!) विफल हो जाएगा। –

1

इसका मतलब है कि फ़ाइल मौजूद नहीं हो सकती है या "केवल पढ़ने के लिए" या "लिखें-संरक्षित" जैसी फ़ाइल तक पहुंचने के दौरान कुछ अनुमति त्रुटि आई है, इसलिए उन मामलों में फॉपेन 0 (एक पूर्ण सूचक) लौटाएगा। सफलता पर यह एक फ़ाइल सूचक को हैंडलर के रूप में वापस कर देगा।

fp=fopen("c:\\ABC.txt", "r");fp=fopen("c:\\abc.txt", "r"); जैसा नहीं हो सकता है।

लिनक्स पर्यावरण में \\ के बजाय // का उपयोग करें।

पी.एस .: लिनक्स और यूनिक्स की तरह ऑपरेटिंग सिस्टम फ़ाइल नाम में केस-संवेदी हैं।

0

यूनिक्स में, फॉपेन() के लिए, fenden() को पास किए गए फ़ाइल नाम पर प्रीपेन्ड करने के लिए कोई कारण नहीं है।

0

मेरे मामले में, मैं थोड़ी देर में एक ही फाइल को फिर से पढ़ रहा था और इसे बंद करना भूल गया था।

मैं फ़ाइल को पढ़ने और एक मैच खोजने के लिए एक समारोह का इस्तेमाल किया और समारोह एक return; बयान है कि fclose(fp) करने से पहले समारोह समाप्त किया था: डी

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