2012-03-06 15 views
7

एक सी ++ प्रोग्राम में, std :: ifstream का उपयोग करके, मैं उपयोगकर्ता द्वारा निर्दिष्ट फ़ाइल खोलने का प्रयास कर रहा हूं - अब तक इतना अच्छा है। हालांकि, मैंने गलती से एक फ़ाइल नाम दर्ज किया जो वास्तव में एक निर्देशिका है, और मैं यह देखकर आश्चर्यचकित था कि खोलने का प्रयास() कि निर्देशिका ने कोई त्रुटि उत्पन्न नहीं की है।ifstream open() त्रुटि बिट्स सेट नहीं करता है जब तर्क एक निर्देशिका है

std::ifstream f; 
f.open(".."); 
if(!f.is_open() || !f.good() || f.bad() || f.fail()) { 
    std::cout << "error bit set on open" << std::endl; 
    return 1; 
} 

त्रुटि का कोई संकेत यहाँ:

यहाँ एक न्यूनतम उदाहरण है। अगर मैं आगे बढ़ता हूं और getline() की कोशिश करता हूं, getline() एक त्रुटि बिट को ठीक से सेट करता है।

std::string str; 
getline(f, str); 

if(f.eof()) std::cout << "getline set eofbit" << std::endl; 
else if(f.bad()) std::cout << "getline set badbit" << std::endl; 
else if(f.fail()) std::cout << "getline set failbit" << std::endl; 

यह आउटपुट "गेटलाइन सेट बैडबिट" है, जो उचित है। >> ऑपरेटर का उपयोग करना एक अंडरफ्लो अपवाद फेंकता है, जो भी ठीक है।

अब, मेरा सवाल यह है कि, मैं कैसे पता लगा सकता हूं कि उपयोगकर्ता ने उचित फ़ाइल नाम के बजाय निर्देशिका नाम दर्ज किया है? क्या उसे करने का कोई तरीका है? स्ट्रीम से बाइट प्राप्त करना और अनजान करना कठिन और त्रुटि-प्रवण प्रतीत होता है।

इसके अलावा, ऐसा क्यों है? मुझे एहसास है कि कार्यक्रम के दृष्टिकोण से यह वही डेटा है, लेकिन मुझे लगता है कि ओएस कुछ "अरे, यह एक निर्देशिका है" संदेश भेज देगा।

+0

आप इस व्यवहार को किस मंच पर प्राप्त कर रहे हैं? –

+0

सी ++ में "निर्देशिका" की कोई धारणा नहीं है। आपको कुछ प्लेटफ़ॉर्म-विशिष्ट लाइब्रेरी की आवश्यकता है (जैसे पॉज़िक्स या विंडोज)। –

+0

ओह, उबंटू 10.04, कंपाइलर जीसीसी 4.4.3 है। –

उत्तर

3

आप कहते हैं कि नहीं आपके सिस्टम क्या है, तो यह कहना मुश्किल है, लेकिन आम तौर पर, filebuf::open केवल एक त्रुटि वापस आ जाएगी अगर आपके सिस्टम स्तर खुला विफल रहता है। और मैंने यूनिक्स सिस्टम पर काम किया है जहां आप open() निर्देशिका कर सकते हैं; मैंने कुछ लोगों पर भी काम किया है जहां आप इसे खोलने के बाद पढ़ सकते हैं (कम से कम अगर यह स्थानीय रूप से आरोहित फाइल सिस्टम था)।

इसके बारे में क्या करना है: इसके बारे में मैं सोच सकता हूं कि get पहले अक्षर को आजमाएं, फिर इसे वापस रखें। लेकिन यह विफल रहता है अगर फ़ाइल खाली है, तो यह वास्तव में कोई समाधान नहीं है। सिस्टम स्तर (और पर एक QoI बिंदु दृश्य से, मैं filebuf::open की अपेक्षा करता हूं यदि सिस्टम ने निर्देशिका खोलने की अनुमति दी है), तो आप यह निर्धारित करने के लिए सिस्टम स्तर कॉल (stat यूनिक्स में) का उपयोग कर सकते हैं या नहीं फ़ाइल एक निर्देशिका है या नहीं। (निश्चित रूप से एक दौड़ की स्थिति है, निश्चित रूप से: उस समय के बीच जब आप का पता लगाते हैं, यह एक सामान्य फ़ाइल है, और जिस क्षण आप खुले करते हैं, दूसरी प्रक्रिया फ़ाइल को हटा सकती है और निर्देशिका बना सकती है। शायद यह अक्सर अवसर नहीं है, हालांकि।)

+0

ओह, तो यह मंच-विशिष्ट है, आखिरकार, मैं अनुमान लगा सकता था। स्पष्टीकरण के लिए धन्यवाद। हां, यह लिनक्स पर है (उबंटू, डेबियन पर भी ऐसा ही होता है, असुरक्षित रूप से)। चूंकि मैं यह सुनिश्चित करने की कोशिश कर रहा हूं कि यह एक वैध और पठनीय फाइलस्ट्रीम है जिसमें से मैं सामान पढ़ सकता हूं, प्राप्त करना और भूलना उचित है, हालांकि मुझे क्लीनर समाधान की उम्मीद है। निर्भरता और सिस्टम कॉल ओवरकिल की तरह लगते हैं। मेरा मतलब है, मैं त्रुटि के साथ रह सकता हूं, लेकिन, उम, यह सिर्फ अजीब लग रहा था। –

+1

@ साट: मुझे यह भी लगता है कि यह हार्डवेयर पर उपयोग की जाने वाली अंतर्निहित फाइल सिस्टम के लिए विशिष्ट है (नोट: कुछ ओएस आपको डिस्क पर प्रयुक्त फाइल सिस्टम चुनने की अनुमति देता है)। –

+1

@ लोकी एस्टारी मुझे ऐसा लगता है। आईआईआरसी (यह कोशिश करने के बाद से कुछ समय हो गया है), सोलारिस के तहत, स्थानीय रूप से घुड़सवार डिस्क (यूएफएस) पर काम की गई निर्देशिका पर 'ओपन', लेकिन फाइल सिस्टम एनएफएस नहीं था। –

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