2012-10-15 14 views
5

अगर मैं ifstream का उपयोग कर फ़ाइल से एक लाइन पढ़ता हूं, तो क्या स्ट्रीम को वापस पढ़ने के लिए एक तरीका है जिसे मैंने अभी पढ़ा है, सशर्त रूप से?मैं एक लाइन की शुरुआत में एक आईफस्ट्रीम वापस कैसे वापस कर सकता हूं जिसे सी ++ में पढ़ा गया था?

using namespace std; 
//Some code here 
ifstream ifs(filename); 
string line; 
while(ifs >> line) 
{ 
    //Some code here related to the line I just read 

    if(someCondition == true) 
    { 
    //Go back to the beginning of the line just read 
    } 
    //More code here 
} 

तो अगर someCondition सच है, अगली पंक्ति अगले जबकि लूप यात्रा के दौरान पढ़ा एक ही पंक्ति मैं बस अभी पढ़ा होगा। अन्यथा, अगली देर-लूप पुनरावृत्ति फ़ाइल में निम्न पंक्ति का उपयोग करेगी। अगर आपको और स्पष्टीकरण की आवश्यकता है, तो कृपया पूछने में संकोच न करें। अग्रिम में धन्यवाद!

अद्यतन # 1

तो मैं निम्नलिखित की कोशिश की:

while(ifs >> line) 
{ 
    //Some code here related to the line I just read 
    int place = ifs.tellg(); 
    if(someCondition == true) 
    { 
    //Go back to the beginning of the line just read 
    ifs.seekg(place); 
    } 
    //More code here 
} 

लेकिन जब हालत सच है इसे फिर से एक ही पंक्ति को पढ़ने नहीं है। क्या एक पूर्णांक एक स्वीकार्य प्रकार है?

अद्यतन # 2: समाधान

मेरे तर्क में एक त्रुटि थी। क्योंकि आप पहले से पढ़ी की शुरुआत करने के लिए प्राप्त करने की आवश्यकता

int place = 0; 
while(ifs >> line) 
{ 
    //Some code here related to the line I just read 

    if(someCondition == true) 
    { 
    //Go back to the beginning of the line just read 
    ifs.seekg(place); 
    } 
    place = ifs.tellg(); 
    //More code here 
} 

कॉल tellg करने के लिए() समाप्त करने के लिए ले जाया गया था: यहाँ सही संस्करण में काम करता है कि के रूप में मैं यह उन है कि उत्सुक हैं से किसी के लिए करना चाहते हैं लाइन। मैंने पहली बार टेलग() कहा और स्ट्रीम से पहले seekg() कहा जाता है, इसलिए ऐसा लगता है कि कुछ भी नहीं बदला (क्योंकि यह वास्तव में नहीं था)। योगदान देने हेतु आप सभी का धन्यवाद।

+1

स्ट्रीम और स्थिति() को पढ़ने से पहले स्ट्रीम स्थिति प्राप्त करने के लिए टेलग() का उपयोग करें, जिससे आप पहले से सहेजी गई स्थिति में स्ट्रीम स्थिति सेट कर सकें। –

+1

वैसे, ifs >> स्ट्रिंग के लिए लाइनें नहीं मिल रही हैं, लेकिन शब्दों। गेटलाइन के बारे में धन्यवाद std :: getline –

+0

का उपयोग करें। यह भविष्य में कष्टप्रद कीड़े पैदा हो सकता है। –

उत्तर

3

कोई सीधा रास्ता कहते हैं "वापस अंतिम पंक्ति के शुरू करने के लिए मिल" नहीं है। हालांकि, आप std::istream::tellg() का उपयोग करके रखी गई स्थिति पर वापस आ सकते हैं। यही है, एक पंक्ति पढ़ने से पहले आप स्थिति पर वापस जाने के लिए tellg() और फिर seekg() का उपयोग करेंगे।

हालांकि, अक्सर खोज कार्यों को कॉल करना काफी महंगी है, यानी, मैं फिर से लाइनों को पढ़ने के लिए आवश्यकता को हटाने पर विचार करूंगा।

+0

धन्यवाद। दक्षता मेरी तत्काल चिंता नहीं है, लेकिन मैं इसे बाद में करने के कुछ अन्य तरीकों को देखने की कोशिश करूंगा। अभी मेरा मुख्य फोकस कुछ ऐसा काम कर रहा है जो काम करता है। –

+0

मुझे एक फ़ंक्शन में 40 जीबी फ़ाइल से अक्षर पढ़ने की आवश्यकता है जब तक कि मैं एक अक्षर (डेलीमीटर वर्ण) नहीं दबाता कि फ़ंक्शन को पढ़ना नहीं चाहिए। पिछले चरित्र स्थिति को चिह्नित करने के लिए peek() कम महंगी या tellg() seekg() का उपयोग कर रहा है, जिसे मुझे वापस लौटने की आवश्यकता है? मुझे लगता है कि इनमें से किसी भी का उपयोग नहीं करना चाहिए और केवल अतिरिक्त पढ़ने वाले चरित्र को वापस करना होगा। – bkarj

+0

@ बेहरोज़कारजु: 'पीक()' का उपयोग करना काफी सस्ते है। अनिवार्य रूप से यह 'यह वापस करता है-> gptr()! = This-> egptr()? * यह-> gptr(): यह-> अंडरफ्लो(); '(यह सही ढंग से' char' को 'int' में फैलाता है)। स्ट्रीम मानते हुए यह बफर किया जाता है कि यह एक सूचक सम्मेलन और एक अव्यवस्था है। एक 'peek()' कॉल बहुत अधिक काम करता है। –

3

फ़ाइल में fstream स्थिति स्टोर करें (दस्तावेज़ीकरण देखें)।

पढ़ें लाइन।

यदि स्थिति होती है - फ़ाइल में संग्रहीत स्थिति पर जाएं।

आप इस की जरूरत है: