2010-02-27 15 views
8

मुझे लाइन से लाइन को पढ़ने के लिए unistd.h से पढ़ने के फ़ंक्शन का उपयोग करना है। मेरे पास इस समय है:unistd.h पढ़ें() फ़ंक्शन: लाइन द्वारा फ़ाइल लाइन को कैसे पढ़ा जाए?

n = read(fd, str, size); 

हालांकि, यह फ़ाइल के अंत तक या बाइट्स के आकार संख्या तक पढ़ता है। क्या कोई तरीका है कि मैं इसे एक समय में एक पंक्ति को पढ़ सकता हूं, एक नई लाइन पर रोक रहा हूं? रेखाएं सभी परिवर्तनीय लंबाई हैं। ।

#include <unistd.h> 
#include <fcntl.h> 

व्यायाम की बात लाइन द्वारा एक फ़ाइल लाइन में पढ़ने के लिए है, और उत्पादन प्रत्येक पंक्ति के रूप में यह में पढ़ा है असल में, नकल करने के लिए:

मैं केवल इन दो हेडर फाइल अनुमति fgets() और fputs() फ़ंक्शन।

+0

आपको 'fputs()' की नकल करने के लिए 'लिखें()' का उपयोग करने की आवश्यकता होगी - आप इसे पढ़ने के साथ नहीं कर सकते हैं :) –

उत्तर

8

आप चरित्र द्वारा चरित्र को एक बफर में पढ़ सकते हैं और विंडोज़ के लिए लाइनरबैक प्रतीकों (\r\n और यूनिक्स सिस्टम के लिए \n) की जांच कर सकते हैं।

0

यह एक अच्छा सवाल है, लेकिन केवल पढ़ने के फ़ंक्शन की अनुमति नहीं है! : पी

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

गतिशील स्मृति का उपयोग करें।

बफर का आकार बड़ा, कम पढ़ने वाली कॉल का उपयोग किया जाता है (जो एक सिस्टम कॉल है, इसलिए कोई सस्ता नहीं है लेकिन आजकल प्रीपेप्टिव कर्नेल हैं)।

...

या आप पाठ मोड फिर Windows "में फ़ाइल खोलने, तो बस एक अधिकतम लाइन की लंबाई को ठीक, और यदि आप जल्दी होने की जरूरत है fgets उपयोग करते हैं, ...

0

\ r \ n "चुपचाप अनुवाद किया जाएगा" \ n "जैसा कि फ़ाइल पढ़ी जाती है।

यदि आप यूनिक्स पर हैं तो आप गैर-मानक gcc 'getline()' फ़ंक्शन का उपयोग कर सकते हैं।


getline() समारोह POSIX 2008

+3

ओपी फ़ाइल डिस्क्रिप्टर से पढ़ना चाहता है, न कि FILE स्ट्रीम। getline() एक FILE स्ट्रीम से पढ़ता है और की आवश्यकता होती है, जिसकी अनुमति नहीं है। – SzG

0

खैर में मानक है, यह एक टर्मिनल से पंक्ति-दर-पंक्ति पढ़ा जाएगा।

कुछ विकल्प आपके पास हैं:

  • एक समारोह को पढ़ने का उपयोग करता है लिखें जब यह डेटा खत्म हो जाता है, लेकिन केवल फोन करने वाले
  • उपयोग पुस्तकालय करता है में कार्य करने के लिए एक समय में एक लाइन रिटर्न बिल्कुल वह: fgets()
  • एक समय में केवल एक बाइट पढ़ें, इसलिए आप बहुत दूर नहीं जाते हैं।
1

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

4

आप अपनी सबसे लंबी लाइन की लंबाई से दो बार बफर बनाना चाहते हैं, और आपको अपने बफर स्थिति का ट्रैक रखना होगा।

असल में, प्रत्येक बार जब आप एक नई लाइन के लिए बुलाए जाते हैं तो आप अंतराल के मार्कर की तलाश में अपने वर्तमान बफर स्थिति से स्कैन करेंगे। यदि आपको एक अच्छा लगता है, तो यह आपकी लाइन है। अपने बफर पॉइंटर्स को अपडेट करें और वापस आएं।

यदि आप अपनी अधिकतम लम्बाई को दबाते हैं तो आप एक कटा हुआ रेखा वापस कर देते हैं और अपने राज्य को त्यागने के लिए बदल देते हैं। अगली बार जब आपको बुलाया जाता है तो आपको लाइन के अगले छोर तक त्यागने की आवश्यकता होती है, और फिर अपना सामान्य पठन स्थिति दर्ज करें।

यदि आपने जो पढ़ा है, उसके अंत में आप हिट करते हैं, तो आपको बफर की शुरुआत में लपेटने के लिए एक और अधिकतम सीमा वर्णों में पढ़ने की आवश्यकता है, यदि आप नीचे हिट करते हैं (यानी, आपको दो पढ़ने की कॉल करने की आवश्यकता हो सकती है) और फिर स्कैनिंग जारी रखें।

उपर्युक्त सभी मानते हैं कि आप अधिकतम पंक्ति लंबाई निर्धारित कर सकते हैं। यदि आप नहीं कर सकते हैं तो आपको गतिशील स्मृति के साथ काम करना होगा और बफर मॉलोक विफल होने पर क्या होता है इसके बारे में चिंता करें। साथ ही, यदि आप अपने बफर में पढ़ते समय फ़ाइल के अंत को दबाते हैं तो आपको हमेशा पढ़ने के परिणामों की जांच करनी होगी।

1

यदि आपको read() का उपयोग करके बिल्कुल 1 लाइन (और ओवरस्टेप) पढ़ने की आवश्यकता नहीं है, तो ऐसा करने का एकमात्र आम तौर पर लागू तरीका एक समय में 1 बाइट पढ़कर और एक नई बाइट प्राप्त करने तक लूपिंग कर रहा है। हालांकि, यदि आपकी फ़ाइल डिस्क्रिप्टर टर्मिनल को संदर्भित करती है और यह डिफ़ॉल्ट (कैनोनिकल) मोड में है, तो पढ़ाई एक नई लाइन के लिए प्रतीक्षा करेगी और जैसे ही लाइन उपलब्ध हो, अनुरोधित आकार से कम वापस आ जाएगी। यदि डेटा बहुत जल्दी आता है, या 1 लाइन से कम यदि आपके प्रोग्राम का बफर या आंतरिक टर्मिनल बफर लाइन की लंबाई से छोटा है तो यह एक से अधिक पंक्तियों को वापस कर सकता है।

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

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