2009-12-23 15 views
5

मुझे पहले से ही fscanf() का उपयोग करके एक टेक्स्ट फ़ाइल पढ़ने के लिए कुछ कोड मिल गया है, और अब मुझे इसे संशोधित करने की आवश्यकता है ताकि पहले जो व्हाइटस्पेस मुक्त हो, वे व्हाइटस्पेस को अनुमति दें।fscanf() व्हाइटस्पेस पढ़ सकते हैं?

शीर्षक: पाठ फ़ाइल के रूप में मूल रूप से है डेटा
शीर्षक: आंकड़े
आदि ...

जो है मूल रूप सेfgets(inputLine, 512, inputFile); sscanf(inputLine, "%*s %s", &data); का उपयोग कर पार्स, डेटा क्षेत्रों पढ़ने और शीर्षक को अनदेखा कर रहा है, लेकिन अब कुछ डेटा फ़ील्ड को रिक्त स्थान की अनुमति देने की आवश्यकता है। मुझे अभी भी इसके बाद शीर्षक और व्हाइटस्पेस को तुरंत अनदेखा करने की आवश्यकता है, लेकिन फिर व्हाइटस्पेस समेत बाकी पंक्ति में पढ़ा जाए।

क्या sscanf() फ़ंक्शन के साथ ऐसा करने के लिए वैसे भी है?

यदि नहीं, तो व्हाइटस्पेस को सही तरीके से संभालने के लिए कोड में सबसे छोटा परिवर्तन क्या हो सकता है?

अपडेट: मैंने fscanf() को fgets() + sscanf() के साथ बदलने के लिए प्रश्न संपादित किया, जो मेरा कोड वास्तव में उपयोग कर रहा है। मैंने वास्तव में यह नहीं सोचा था कि यह प्रासंगिक था जब मैंने पहली बार सवाल लिखा था, इसलिए मैंने इसे fscanf() में सरल बना दिया।

+0

यदि आप 'स्कैनफ़'' का उपयोग करके इसे पार्स करते थे, तो आप पहले 'शीर्षक: डेटा शीर्षक: डेटा' (यानी सभी एक पंक्ति पर) का विश्लेषण कर सकते थे। यदि आप मूल्यों में व्हाइटस्पेस को अनुमति देना चाहते हैं, तो टर्मिनेटर क्या होगा? यदि नई लाइन है, तो ऐसा लगता है कि आपका मूल कोड थोड़ा सा था ... –

+0

इसके अलावा, आप 'str' buffer के आकार पर कैसे निर्णय लेते हैं, और आप कैसे सुनिश्चित करते हैं कि यह अतिप्रवाह नहीं है? –

+0

हां, जब डेटा में व्हाइटस्पेस हो सकता है तो नई लाइन टर्मिनेटर –

उत्तर

11

साथ आप fgets() उपयोग नहीं कर सकते %[ रूपांतरण विनिर्देशक का उपयोग "को बाहर विकल्प"):

char buf[100]; 
fscanf(stdin, "%*s %99[^\n]", buf); 
printf("value read: [%s]\n", buf); 

लेकिन fgets() बेहतर तरीका है।


संपादित करें: fgets() + sscanf()

char buf[100], title[100]; 
fgets(buf, sizeof buf, stdin); /* expect string like "title: TITLE WITH SPACES" */ 
sscanf(buf, "%*s %99[^\n]", title); 
+3

इस विशेष मामले के लिए, 'fgets'' तरीका बेहतर कैसे है? –

+1

अच्छा ... आवश्यकताओं को बदलते रहें (पहले स्ट्रिंग में कोई जगह नहीं थी)। यह इस विशेष मामले के लिए बेहतर नहीं है, लेकिन आवश्यकताओं के अगले परिवर्तन के लिए अब उत्तेजना में 'fgets() 'का उपयोग करना बेहतर है :) – pmg

+0

मैंने यह दिखाने के लिए प्रश्न अपडेट किया कि मैं वास्तव में पढ़ने के लिए fgets() का उपयोग करता हूं लाइन, फिर sscanf() इसे पार्स करने के लिए, लेकिन क्या fgets() के बाद लाइन को पार्स करने का कोई बेहतर तरीका है? –

3

मुझे अत्यधिक सुझाव है कि आप fscanf() का उपयोग करना बंद करें और fgets() (जो एक पूरी लाइन पढ़ता है) का उपयोग शुरू करें और फिर पढ़ी गई रेखा को पार्स करें।

इससे आपको गैर-सटीक रूप से स्वरूपित इनपुट को पार्स करने के संबंध में काफी अधिक स्वतंत्रता मिल जाएगी।

+0

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

+1

एक बार जब आप पूरी स्ट्रिंग प्राप्त कर लेंगे, तो एसएसकेएनएफ का उपयोग करने के बजाय इसे स्वयं चलाएं। –

+0

हां, पॉइंटर्स के साथ ऐसा करें, या नियमित अभिव्यक्तियों का बेहतर उपयोग करें। यदि आपने सी ++ का उपयोग किया तो मैंने बढ़ावा दिया होगा; मुझे किसी भी अच्छे सी पुस्तकालयों के बारे में पता नहीं है लेकिन कुछ होना चाहिए। मैंने सुना है कि पॉज़िक्स उनका समर्थन करता है। –

2

सरल बात पहले भाग को छोड़ने के लिए एक

fscanf("%*s"); 

जारी करने के लिए किया जाएगा और फिर बस fgets फोन: (

fgets(str, stringSize, filePtr); 
3

आप scanf उपयोग कर, और यह सोचते हैं कि आप एक टर्मिनेटर के रूप में न्यू लाइन चाहते हैं पर जोर देते हैं, तो साथ संस्करण, आप यह कर सकते हैं:

scanf("%*s %[^\n]", str); 

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

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

2

एक %s विनिर्देशक fscanf में इनपुट पर कोई श्वेत रिक्ति को छोड़ देता है, तो अप करने के लिए और अगले खाली स्थान के चरित्र सहित नहीं गैर-सफ़ेद वर्णों की स्ट्रिंग पढ़ता है।

यदि आप एक नई लाइन तक पढ़ना चाहते हैं, तो आप एक निर्दिष्ट के रूप में %[^\n] का उपयोग कर सकते हैं। इसके अलावा, प्रारूप स्ट्रिंग में '' 'इनपुट पर व्हाइटस्पेस छोड़ देगा। तो अगर आप का उपयोग करें यदि

fscanf("%*s %[^\n]", &str); 

यह ("title:" अपने मामले में) पहले खाली स्थान के अप करने के लिए लाइन पर पहली बात यह है पढ़ा जाएगा, और इसे फेंक, तो खाली स्थान के वर्ण पढ़ सकते हैं और उन्हें दूर फेंक देते हैं, फिर सभी वर्णों को स्ट्रिंग में एक नई लाइन तक पढ़ा जाएगा, जो आप चाहते हैं की तरह लगता है। (100 वर्ण, एक को समाप्त NUL यहाँ गिनती नहीं) आप

fscanf("%*s %100[^\n]", &str) 

उपयोग करने के लिए अधिकतम स्ट्रिंग लंबाई आप पढ़ेंगे सीमित करने के लिए चाहते हो सकता है -

सावधान कि str अतिप्रवाह नहीं करता है।

+0

मुझे पता है कि यह एक छोटा है उदाहरण लेकिन क्या आपको str के पते का उपयोग करना है? मुझे लगता है कि यह भी काम करेगा। 'fscanf ("% * s% [^ \ n] ", str);' – cokedude

1

आप *scanf परिवार के लिए क्या अच्छा है इसकी सीमाओं के खिलाफ चल रहे हैं। काफी कम परिवर्तन के साथ आप डेव हैंनसन के C Interfaces and Implementations से स्ट्रिंग-स्कैनिंग मॉड्यूल का उपयोग करने का प्रयास कर सकते हैं। यह सामान प्रोग्रामिंग भाषा Icon से एक रेट्रोफिट है, जो बेहद सरल और शक्तिशाली स्ट्रिंग-प्रोसेसिंग भाषा है जो हैनसन और अन्य एरिजोना में काम करते थे। sscanf से प्रस्थान बहुत गंभीर नहीं होगा, और यह सरल, आसान काम करने के साथ आसान और आसान है। केवल नीचे की ओर यह है कि कोड — पुस्तक के बिना पालन करना थोड़ा मुश्किल है, लेकिन यदि आप बहुत सी प्रोग्रामिंग करते हैं, तो पुस्तक अच्छी तरह से योग्य है।

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