2012-05-21 14 views
6
class Person { 
private: 
    string firstName; 
    string lastName; 
public: 
    Person() {} 

    Person(ifstream &fin) { 
     fin >> firstName >> lastName; 
    } 

    void print() { 
     cout << firstName 
      << " " 
      << lastName 
      << endl; 
    } 
}; 

int main() { 
    vector<Person> v; 
    ifstream fin("people.txt"); 

    while (true) { 
     Person p(fin); 
     if (fin == NULL) { break; } 
     v.push_back(p); 
    } 

    for (size_t i = 0; i < v.size(); i++) { 
     v[i].print(); 
    } 

    fin.close(); 
    return 0; 
} 

का उपयोग कर फ़ाइल पढ़ना कृपया मुझे बताएं कि कोड स्निपेट निम्न कैसे काम करता है? अगर (फिन == न्यूल) {ब्रेक; }सी ++, ifstream

फिन स्टैक पर एक वस्तु है, सूचक नहीं है इसलिए यह पूर्ण नहीं हो सकता है। मैं ifstream कक्षा में अधिभारित ऑपरेटर == फ़ंक्शन नहीं ढूंढ पाया। तो मैं समझ नहीं पा रहा हूं कि यह स्निपेट कैसे काम करता है।

उत्तर

5

ifstream कक्षा में operator void *() (or operator bool() in C++11) है। यह तब कहा जाता है जब आप (fin == NULL) का परीक्षण करते हैं।

परीक्षण fin == NULL परीक्षण fin.fail() परीक्षण के समान होना चाहिए।

+0

आपको बहुत बहुत धन्यवाद। आपका उत्तर बहुत उपयोगी था। – Yoh0xFF

3

istream और ostream के मूल वर्गों में अंतर्निहित रूपांतरण फ़ंक्शन हैं, जो उन्हें बूलियन मान के रूप में उपयोग करने की अनुमति देते हैं; प्री-सी ++ 11, में अंतर्निहित रूपांतरण void* था।

यह आशय कभी नहीं था कि इस रूपांतरण के परिणाम एक सूचक के रूप में इस्तेमाल किया जा, और fin == NULL की तरह कोड सी की एक अत्यंत गरीब समझ ++ और मानक धाराओं को दर्शाता है। पहले पाश लिख की मुहावरेदार रास्ता एक डिफ़ॉल्ट निर्माता और Person के लिए एक operator>> परिभाषित करने के लिए किया जाएगा, और उसके बाद लिखें:

Person p; 
while (fin >> p) { 
    v.push_back(p); 
} 

(और जब मैं इसे पर हूँ: क्या तुम सच में वापसी मान का परीक्षण करना चाहिए fin.close() की, और 0 वापस नहीं अगर यह विफल:।

fin.close(); 
return fin ? EXIT_SUCCESS : EXIT_FAILURE; 

)

+0

जबकि मैं मानता हूं कि यह संभवतः ऐसा करने का सबसे अच्छा अभ्यास होगा, मैंने ** कभी ** कोड नहीं देखा है जो जांच करता है कि बंद होना सफल था या वापसी मूल्य समायोजित करना था। निजी तौर पर, मैं कभी भी 'करीबी' को कॉल नहीं करता, इसके बजाय आरएआईआई पर भरोसा करता हूं - लेकिन सौभाग्य से मैं लेखन कोड से दूर हो सकता हूं जो मजबूत आईओ नहीं करता है। –

+0

@ कोनराड रुडॉल्फ: मुझे लगता है कि आरएआईआई पर निर्भर होने का तात्पर्य है कि विनाशक परीक्षण नहीं करता है कि बंद होना सफल था या नहीं। कॉलर को ऐसी त्रुटि स्थिति को परिवहन करने का कोई साधन नहीं है (जब तक आप वैश्विक चर का सहारा लेते हैं)। –

+0

@ फ़्रेरिक निश्चित रूप से। जैसे मैंने कहा, मैं गैर-मजबूत आईओ करने से दूर हो सकता हूं। आलसी, मुझे पता है, लेकिन यह कोड को बहुत सरल और क्लीनर बनाता है। –

2

यह सेंट नहीं कैसे है रेम्स का इस्तेमाल किया जाना चाहिए। सच है, यह (दुर्भाग्य से!) संकलित करता है और यहां तक ​​कि "सही" चीज भी करता है। लेकिन इस तरह कोड नहीं लिखें। जो भी इस कोड को लिखा है शायद सोचा था कि वे चालाक थे।

लेकिन उन्होंने वास्तव में क्या किया, एक वास्तविक, अपरंपरागत एपीआई पेश करके सी ++ प्रोग्रामर की अपेक्षाओं को तोड़ दिया, बिना किसी वास्तविक फायदे के।

यह कोड इनपुट स्ट्रीम से Person प्रकार का ऑब्जेक्ट प्रारंभ करता है। दुर्भाग्य से, ऐसा करके, कोड ऑब्जेक्ट पढ़ने के दौरान त्रुटियों का परीक्षण करने का अवसर छोड़ देता है। यह अच्छा नहीं है। एक ऑब्जेक्ट में कोई इनपुट स्ट्रीम स्वीकार करने वाला कोई कन्स्ट्रक्टर नहीं होना चाहिए, इसे operator>> अधिभारित करना चाहिए।

+0

शैतानों को बजाना यहां वकील है: मुझे लगता है कि एक निर्माता को एक धारा पारित करने से पूर्ण ज्ञान मिलता है। आप त्रुटियों को सिग्नल करने के लिए अपवादों का उपयोग कर सकते हैं, और आप अनियमित वस्तुओं की संभावना होने की समस्या से बचते हैं (आपके सुझाए गए विकल्प के विपरीत, जो ऑब्जेक्ट बनाने की अनुमति देता है लेकिन 'ऑपरेटर >>' का उपयोग नहीं करता है)। –

+0

@ फ्रैरिक सिद्धांत रूप में, मैं पूरी तरह से आपसे सहमत हूं। यही कारण है कि मैंने कहा कि यह एक प्रोग्रामर था जो जेम्स के बजाए चालाक था, जिसने सोचा कि यह कोई ऐसा व्यक्ति है जो धाराओं के बारे में अनजान है। लेकिन यह अभी भी अपेक्षाओं को तोड़ता है और मौजूदा स्ट्रीम लाइब्रेरी के ऊपर सी ++ इमारत में शायद एक अच्छा विचार नहीं है। स्ट्रीम को बहुत बेहतर किया जा सकता है, लेकिन फिर अपनी लाइब्रेरी बनाएं, मौजूदा पैटर्न के शीर्ष पर न बनाएं जो अलग-अलग काम करता है। –