2011-10-21 22 views
6

सेट किए बिना getline() का उपयोग करें सेट किए बिना वैध फ़ाइल पढ़ने के लिए getline() का उपयोग करना संभव है? मैं failbit का उपयोग करना चाहता हूं ताकि इनपुट फ़ाइल पठनीय न हो तो अपवाद उत्पन्न होता है।विफलता

निम्न कोड हमेशा अंतिम पंक्ति के रूप में basic_ios::clear आउटपुट करता है - भले ही वैध इनपुट निर्दिष्ट किया गया हो।

test.cc:

#include <iostream> 
#include <string> 
#include <fstream> 
using namespace std; 

int main(int argc, char* argv[]) 
{ 
    ifstream inf; 
    string line; 

    inf.exceptions(ifstream::failbit); 
    try { 
     inf.open(argv[1]); 
     while(getline(inf,line)) 
      cout << line << endl; 
     inf.close(); 
    } catch(ifstream::failure e) { 
     cout << e.what() << endl; 
    } 
} 

input.txt:

the first line 
the second line 
the last line 

परिणाम:

$ ./a.out input.txt 
the first line 
the second line 
the last line 
basic_ios::clear 
+0

जब आप उम्मीद करते हैं जब getline का उपयोग कर failbit उठाया जा()? – selalerer

+0

अगर फ़ाइल मौजूद नहीं है। उदाहरण के लिए './a.out nosuchfile.txt' – Jeremiah

+0

इसके लिए आप फ़ाइल खोलने के बाद is_open() जांच सकते हैं। – selalerer

उत्तर

6

आप नहीं कर सकते। मानक getline के बारे में कहते हैं: समारोह नहीं वर्ण निकालता है

है, यह is.setstate(ios_base::failbit) कॉल जो ios_base::failure (27.5.5.4) फेंक सकता है।

यदि आपकी फ़ाइल खाली रेखा के साथ समाप्त होती है, यानी अंतिम चरित्र '\ n' है, तो गेटलाइन के लिए अंतिम कॉल कोई वर्ण नहीं पढ़ता है और विफल रहता है। दरअसल, आप लूप को कैसे समाप्त करना चाहते हैं अगर यह असफलता सेट नहीं करेगा? while की स्थिति हमेशा सत्य होगी और यह हमेशा के लिए चली जाएगी।

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

वैसे भी, ऊपर कोड के रूप में लिखा जाना चाहिए:

try { 
    ifstream inf(argv[1]); 
    if(!inf) throw SomeError("Cannot open file", argv[1]); 
    string line; 
    while(getline(inf,line)) 
     cout << line << endl; 
    inf.close(); 
} catch(const std::exception& e) { 
    cout << e.what() << endl; 
} 
+0

'विफलता' सीमाओं को समझाने के लिए धन्यवाद। आपका कार्यान्वयन काम करता है। – Jeremiah