स्कैनफ़ प्रारूप स्ट्रिंग
एक स्कैनएफ फॉर्मेट स्ट्रिंग (स्कैन एफऑर्मेटेड) एक इनपुट स्ट्रिंग के लेआउट को निर्दिष्ट करने के लिए विभिन्न फ़ंक्शन में उपयोग किया जाने वाला एक कण्ट्रोल पैरामीटर होता है। फ़ंक्शंस तब स्ट्रिंग को विभाजित कर सकते हैं और उचित डेटा प्रकार के वैल्यू में अनुवाद कर सकते हैं। स्ट्रिंग स्कैनिंग फ़ंक्शंस अधिकांशतः स्टैण्डर्ड लाइब्रेरीज में प्रदान किए जाते हैं। स्कैनफ़ एक फ़ंक्शन होता है जो स्टैण्डर्ड इनपुट स्ट्रिंग से स्वरूपित डेटा को रीड है, जो सावैल्यू ्यतः कीबोर्ड होता है और जब भी स्पेसीफाईड आर्गुमेंट्स में बुलाया जाता है तो यह परिणाम लिखता है।
स्कैनएफ शब्द सी स्टैण्डर्ड लाइब्रेरी से आया है, जिसने इस प्रकार के फ़ंक्शन को लोकप्रिय बनाया, परन्तु ऐसे फ़ंक्शन C से पहले के होते हैं, और अन्य नामों का उपयोग किया जाता है, जैसे रीडएफ
का ALGOL 68 में किया जाता है। स्कैनफ फॉर्मेट स्ट्रिंग्स, जो स्वरूपित इनपुट ( प्रेसिंग ) प्रदान करते हैं, प्रिंटएफ फॉर्मेट स्ट्रिंग के कॉम्प्लीमेंट होते हैं, जो स्वरूपित आउटपुट (टेम्पलेटिंग भाषा) प्रदान करते हैं। ये अधिक सोफिस्टिकेटेड और फ्लेक्सिबल पार्सर या टेम्पलेट इंजन की तुलना में सरल कार्यक्षमता और निश्चित फॉर्मेट प्रदान करते हैं, परन्तु कई उद्देश्यों के लिए पर्याप्त होते हैं।
इतिहास
माइक लेस्क की पोर्टेबल इनपुट/आउटपुट लाइब्रेरी, स्कैनफ़
सहित, आधिकारिक तौर पर संस्करण 7 यूनिक्स में यूनिक्स का भाग बन गया।[1]
उपयोग
स्कैनफ़
फ़ंक्शन, जो सी प्रोग्रामिंग भाषा में पाया जाता है, स्टैण्डर्ड इनपुट (अधिकांशतः एक कमांड लाइन इंटरफेस या सवैल्यू प्रकार का टेक्स्ट यूजर इंटरफ़ेस) से नंबरओं और अन्य डेटा प्रकार के लिए इनपुट रीड करता है।
निम्नलिखित सी कोड स्टैण्डर्ड इनपुट स्ट्रीम से अस्वरूपित डेसीमल पूर्णांकों की एक चर नंबर को रीड करता है और उनमें से प्रत्येक को भिन्न-भिन्न पंक्तियों में प्रिंट करता है:
#include <stdio.h>
int main(void)
{
int n;
while (scanf("%d", &n) == 1)
printf("%d\n", n);
return 0;
}
उपरोक्त प्रोग्राम द्वारा संसाधित होने के पश्चात्, पूर्णांकों की एक अनियमित स्पेस वाली लिस्ट जैसे
456 123 789 456 12 456 1 2378
कांस्टेंट स्पेस पर इस प्रकार दिखाई देगा:
456 123 789 456 12 456 1 2378
किसी शब्द का प्रिंट आउट लेने के लिए:
#include <stdio.h>
int main(void)
{
char word[20];
if (scanf("%19s", word) == 1)
puts(word);
return 0;
}
इससे कोई अंतर नहीं पड़ता कि प्रोग्रामर किस डेटा प्रकार को रीड करना चाहता है, आर्गुमेंट (जैसे &n
ऊपर) मेमोरी की ओर पॉइंट करने वाला पॉइंटर होना चाहिए। अन्यथा, फ़ंक्शन सही विधि से प्रदर्शन नहीं करेगा क्योंकि यह उस वेरिएबल के मेमोरी स्पेस को पॉइंट करने के अतिरिक्त मेमोरी के गलत अनुभागों को ओवरराइट करने का प्रयास करेगा जिसके लिए आप इनपुट प्राप्त करने का प्रयास कर रहे हैं।
अंतिम उदाहरण में एड्रेस-ऑफ ऑपरेटर (&
) का उपयोग आर्गुमेंट के लिए नहीं किया जाता है: जैसावर्ड
की चूंकि शब्द char
एक सारणी डेटा संरचना का नाम है , इस प्रकार यह (सभी संदर्भों में जिसमें यह किसी एड्रेस का मूल्यांकन करता है) ऐरे के पहले तत्व के पॉइंटर के सवैल्यू होता है। जबकि अभिव्यक्ति &word
नंबरत्मक रूप से सवैल्यू मूल्य पर मूल्यांकन करेगा, शब्दार्थ की दृष्टि से, इसका एक बिल्कुल अलग अर्थ है कि यह इसके एक तत्व के अतिरिक्त पूरे ऐरे के पते को प्रदर्शित करता है। स्कैनफ़
स्ट्रिंग्स के लिए आउटपुट नियुक्ति करते समय इस तथ्य को ध्यान में रखा जाना चाहिए ।
चूँकि स्कैनफ़
को मात्र स्टैण्डर्ड इनपुट से पढ़ने के लिए निर्दिष्ट किया गया है, इंटरफ़ेस वाली कई प्रोग्रामिंग भाषाओं, जैसे PHP, एसस्कैनफ़
और एफस्कैनफ़ जैसे
डेरिवेटिव होते हैं ,परन्तु स्वयं स्कैनफ़
नही होता है।
फॉर्मेट स्ट्रिंग विनिर्देश
स्कैनफ़
में फ़ॉर्मेटिंग प्लेसहोल्डर निम् और अधिकप्रिंटएफ
के सवैल्यू ही होता हैं, यह एक रिवर्स फ़ंक्शन होता है। प्रिंटएफ की तरह, POSIX एक्सटेंशन n$
को परिभाषित किया गया है।[2]
फॉर्मेट स्ट्रिंग में संभाव्यता ही कभी कांस्टेंट होते हैं (अर्थात, करैक्टर जो प्लेसहोल्डर को स्वरूपित नहीं कर रहे हैं), मुख्यतः क्योंकि एक प्रोग्राम सामान्यतः ज्ञात डेटा को पढ़ने के लिए डिज़ाइन नहीं किया जाता है, यघपि स्कैनफ़
यदि स्पष्ट रूप से निर्दिष्ट किया गया है तो इन्हें स्वीकार करता है। अपवाद एक या अधिक व्हाइटस्पेस कैरेक्टर होते है, जो इनपुट में सभी व्हाइटस्पेस कैरेक्टर को हटा देता है।[2]
सबसे अधिक उपयोग किए जाने वाले कुछ प्लेसहोल्डर इस प्रकार हैं:
%a
: एक फ़्लोटिंग-पॉइंट नंबर को उसके हेक्साडेसिमल नोटेशन में स्कैन करें।%d
: एक पूर्णांक को साइंड डेसीमल नंबर के रूप में स्कैन करें।%i
: एक पूर्णांक को साइंड नंबर के रूप में स्कैन करें।%d
के सवैल्यू परन्तु,0x
से पहले आने पर नंबर को हेक्साडेसिमल और0
से पहले होने पर ऑक्टल के रूप में व्याख्या करता है। उदाहरण के लिए, स्ट्रिंग031
को%d
का उपयोग करके 31 और%i
का उपयोग करके 25 रके ूप में पढ़ा जाएगा।%hi
में फ्लैगh
में कन्वर्शन औरhh
एकchar
में कन्वर्शन को पॉइंट करता है।%u
: डेसीमलअनसाइंड इंट
के लिए स्कैन करें(ध्यान दें कि C99 स्टैण्डर्ड में इनपुट वैल्यू नेगेटिव साइन वैकल्पिक होते है, इसलिए यदि नेगेटिव साइन पढ़ा जाता है, तो कोई एरर उत्पन्न नहीं होगी और परिणाम एक नेगेटिव नंबर का कॉम्प्लीमेंट होगा, संभवतः यह एक बहुत बड़ा वैल्यू होती है। देखेंstrtoul()
तदनुसार,%hu
एकअनसाइंड शोर्ट
के लिए स्कैन करता है और%hhu
एकअनसाइंड चार
के लिए स्कैन करता है।%f
: एक फ्लोटिंग पॉइंट नंबर को (फ़िक्स्ड-पॉइंट) नोटेशन में स्कैन करें।%g
,%G
: किसी फ़्लोटिंग-पॉइंट नंबर को नार्मल या एक्सपोनेंशियल नोटेशन में स्कैन करें।%g
लोअर-केस का उपयोग करता है और%G
अपर-केस का उपयोग करता है.%x
,%X
: एक पूर्णांक को असाइंड हेक्साडेसिमल नंबर के रूप में स्कैन करें।%o
: एक पूर्णांक को ऑक्टल नंबर के रूप में स्कैन करें।%s
: एक करैक्टर स्ट्रिंग को स्कैन करें। स्कैन व्हाइटस्पेस पर टर्मिनेट होता है। स्ट्रिंग के अंत में एक नल करैक्टर स्टोर होता है, जिसका अर्थ है कि आपूर्ति किया गया बफ़र निर्दिष्ट इनपुट लेंग्थ से कम से कम एक करैक्टर लेंग्थ होना चाहिए।%c
: एक करैक्टर (चार) को स्कैन करें। कोई जीरो करैक्टर नहीं जोड़ा गया है।- व्हाइटस्पेस: कोई भी व्हाइटस्पेस करैक्टर जीरो या अधिक व्हाइटस्पेस करैक्टरों के लिए स्कैन ट्रिगर करता है। रिक्त स्पेस करैक्टरों की नंबर और प्रकार का किसी भी दिशा में मिलान करने की आवश्यकता नहीं होती है।
%lf:
डबल फ़्लोटिंग-पॉइंट नंबर रूप में स्कैन करें। "लॉन्ग" स्पेसिफायर के साथ "फ़्लोट" फॉर्मेट।%Lf
: एक लॉन्ग डबल फ़्लोटिंग-पॉइंट नंबर के रूप में स्कैन करें। "लॉन्ग लॉन्ग" स्पेसिफायर को "फ़्लोट" करें।%n
: कुछ भी अपेक्षित नहीं है। इनपुट से अब तक कंज्यूम किए गए करैक्टरों की नंबर अगले पॉइंटर के माध्यम से स्टोर की जाती है, जो कि इंट का पॉइंटर होना चाहिए। यह कन्वर्शन नहीं है और फ़ंक्शन द्वारा रिटर्न गई नंबर में वृद्धि नहीं करता है।
उपरोक्त का उपयोग नंबर मॉडिफ़ायर औरl
, L
मॉडिफ़ायर के साथ संयोजन में किया जा सकता है जो प्रतिशत साइन और करैक्टर के मध्य में "लॉन्ग" और "लॉन्ग लॉन्ग" तक स्टैंड रहते हैं। प्रतिशत साइन और उससे पहले के करैक्टरों के मध्य नंबर वैल्यू भी हो सकते हैं, यदि कोई लॉन्ग
मॉडिफ़ायर से पहले हो, जो स्कैन किए जाने वाले करैक्टरों की नंबर निर्दिष्ट करता है। एक वैकल्पिक एस्टरिस्क (*
) प्रतिशत साइन के ठीक पश्चात् यह प्रदर्शित करता है कि इस फॉर्मेट स्पेसिफायर द्वारा रीड किया गया डेटाम एक करैक्टर में स्टोर नहीं किया जाता है। इस गिराए गए चर के लिए फॉर्मेट स्ट्रिंग के पीछे कोई आर्गुमेंट सम्मलित नहीं किया जाना चाहिए।
प्रिंटफ में एफएफ
मॉडिफ़ायर स्कैनएफ में उपस्थिति नहीं होती है, जिससे इनपुट और आउटपुट के मोड के मध्य अंतर पैदा होता है। ll
और hh
मॉडिफ़ायर C90 स्टैण्डर्ड में उपस्थति नहीं होता हैं, परन्तु C99 स्टैण्डर्ड में उपस्थति होता हैं।[3]
फॉर्मेट स्ट्रिंग का एक उदाहरण निम्न प्रकार है
"%7d%s %c%lf"
उपरोक्त फॉर्मेट स्ट्रिंग पहले सात करैक्टरों को डेसीमल पूर्णांक के रूप में स्कैन करती है, फिर शेष को एक स्ट्रिंग के रूप में रीड करती है जब तक कि कोई स्पेस, न्यूलाइन या टैब नहीं मिल जाता है, फिर पहले नॉन-व्हाइटस्पेस करैक्टर मिलने तक व्हाइटस्पेस का कंज्यूम करता है, फिर उस करैक्टर का कंज्यूम करता है, और अंत में शेष करैक्टरों डबल-फ़्लोटिंग-पॉइंट फॉर्मेट फॉर्मेट के रूप में स्कैन करता है। इसलिए, एक रोबस्ट फंक्शन को यह चेक करना चाहिए कि क्या स्कैनफ़
कॉल सफल हुई और उचित एक्शन लें। यदि इनपुट सही फॉर्मेट में नहीं था, तो गलत डेटा अभी भी इनपुट स्ट्रीम पर रहेगा और नए इनपुट को रीड करने से पहले उसे हटा दिया जाना चाहिए। एक वैकल्पिक विधि, जो इससे बचता है, एफगेट्स
का उपयोग करना है और फिर रीड की गई स्ट्रिंग को चेक करें। अंतिम स्टेप एसस्कैनएफ
द्वारा किया जा सकता है, उदाहरण के लिए।
अनेक फ़्लोट प्रकार के करैक्टरों के स्थितियों में a, e, f, g, कई इम्प्लीमेंटेशन अधिकांश को एक ही पार्सर में कोलाप्स करना चयन करते हैं। माइक्रोसॉफ्ट एमएसवीसीआरटी e, f, g इसके साथ करता है,[4] जबकि जीएलआईबीसी चारों के साथ ऐसा करता है।[2]
कमजोरियाँ(वल्नेरेबिलिटीज)
स्कैनफ़
स्ट्रिंग अटैक को फॉर्मेट करने के प्रति संवेदनशील होता है। यह सुनिश्चित करने के लिए बहुत सावधानी बरतनी चाहिए कि फॉर्मेट स्ट्रिंग अटैक स्ट्रिंग और ऐरे आकार की लिमिटेशन सम्मिलित होती हैं। अधिकांश स्थितियों में उपयोगकर्ता से इनपुट स्ट्रिंग का आकार आरबिटरेरी होता है और इसे पहले निर्धारित नहीं किया जा सकता है स्कैनफ़
फ़ंक्शन निष्पादित किया गया है। इस का अर्थ है कि %s
लेंग्थई स्पेसीफायर्स के बिना प्लेसहोल्डर स्वाभाविक रूप से असुरक्षित होते हैं और बफ़र ओवरफ़्लो के लिए एक्सप्लॉइट होते हैं। एक अन्य संभावित समस्या डायनामिक फ़ॉर्मेटिंग स्ट्रिंग्स को अनुमति देना है, उदाहरण के लिए कॉन्फ़िगरेशन फ़ाइलों या अन्य यूजर-कंट्रोल्ड फ़ाइलों में स्टोर्ड फ़ॉर्मेटिंग स्ट्रिंग्स। इस स्थिति में स्ट्रिंग आकार की अनुमत इनपुट लेंग्थई तब तक निर्दिष्ट नहीं की जा सकती जब तक कि फ़ॉर्मेटिंग स्ट्रिंग की पहले से जाँच नहीं की जाती और सीमाएँ प्रयुक्त नहीं की जातीं है। इससे संबंधित अतिरिक्त या बेमेल फ़ॉर्मेटिंग प्लेसहोल्डर होता हैं जो वास्तविक वैरार्ग लिस्ट से मैच नही होता हैं। वैरार्ग के विशेष इम्प्लीमेंटेशन के आधार पर, इन प्लेसहोल्डर्स को आंशिक रूप से स्टैक से निकाला जा सकता है या इसमें अनडिजायरेबल या यहां तक कि इनसिक्योर पॉइंटर्स भी हो सकते हैं।
यह भी देखें
- सी प्रोग्रामिंग भाषा
- स्ट्रिंग अटैक को फॉर्मेट करें
- प्रिंटफ़ फॉर्मेट स्ट्रिंग
- स्ट्रिंग इंटरपोलेशन
संदर्भ
- ↑ McIlroy, M. D. (1987). A Research Unix reader: annotated excerpts from the Programmer's Manual, 1971–1986 (PDF) (Technical report). CSTR. Bell Labs. 139.
- ↑ 2.0 2.1 2.2 Linux Programmer's Manual – Library Functions –
- ↑ C99 standard, §7.19.6.2 "The fscanf function" alinea 11.
- ↑ "स्कैनफ़ प्रकार फ़ील्ड वर्ण". docs.microsoft.com.
बाहरी संबंध
- The Single UNIX Specification, Version 4 from The Open Group – System Interfaces Reference,
- C++ reference for
std::स्कैनफ़