2013-10-21 4 views
14

इस कोड में scanf("%d") और scanf("%d ") के बीच क्या अंतर है, जहां प्रारूप स्ट्रिंग में पिछला खाली अंतर है?स्कैनफ() प्रारूप स्ट्रिंग में सफेद स्थान पीछे पीछे करने का क्या प्रभाव है?

#include <stdio.h> 

int main(void) 
{ 
    int i, j; 

    printf("enter a value for j "); 
    scanf("%d ",&j); 
    printf("j is %d\n", j); 
    printf("enter a value for i "); 
    scanf("%d", &i); 
    printf("i is %d\n", i); 
    return 0; 
} 

कैसे scanf() समारोह वास्तव में जब मैं scanf("%d ", &j); तरह फॉर्मेट स्पेसिफायर के बाद खाली स्थान काम करता है?

उत्तर

16

स्कैनफ प्रारूप में एक सफेद जगह चरित्र इसे स्पष्ट रूप से पढ़ने और अनदेखा करने के कारण कई सफेद जगहों के पात्रों को अनदेखा कर सकता है। तो scanf("%d ", ... के साथ, एक संख्या पढ़ने के बाद, यह सभी सफेद जगहों को छोड़कर वर्णों को पढ़ना जारी रखेगा जब तक कि यह इनपुट पर गैर-व्हाइटस्पेस वर्ण न देखे। उस गैर-व्हाइटस्पेस चरित्र को अगले चरण के रूप में एक इनपुट फ़ंक्शन द्वारा पढ़ा जाएगा।

अपने कोड के साथ

:

printf("enter a value for j "); 

scanf("%d ",&j); 

printf("j is %d \n", j); 

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

enter a value for j 5 
6 
j is 5 
enter a value for i i is 6 

इसके अलावा (सभी के लिए छोड़कर, के बाद से सबसे scanf% -conversions भी अग्रणी खाली स्थान के छोड़ %c, %[ और %n), % से पहले रिकॉर्ड्स अप्रासंगिक ("%d" और " %d" समान रूप से कार्य करेगा)। इसलिए अधिकांश भाग के लिए, आपको स्कैनफ़ रूपांतरणों में रिक्त स्थान से बचना चाहिए जबतक कि आपको पता न हो कि आपको विशेष रूप से उनके असाधारण प्रभाव के लिए उनकी आवश्यकता है।

+0

तो यही कारण है कि यह अगले तक क्यों लटकता है गैर-सफेद अंतरिक्ष चरित्र इसलिए है क्योंकि यह सुनिश्चित करना चाहता है कि "ठीक है, यह सब (लम्प्ड) सफेद जगह है जिसे मैं मिलान कर सकता हूं"? –

1

अंतर (हालांकि स्पष्ट) एक अलग प्रारूप स्ट्रिंग है। आप निम्न पंक्ति डालें:

"3  "

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

scanf() आपके द्वारा प्रदान की जाने वाली प्रारूप स्ट्रिंग से सटीक रूप से मिलान करने के लिए प्रदान किए गए इनपुट की अपेक्षा करता है, अपवाद के साथ कि whitespace अक्षर एक ही सफेद स्थान चरित्र पर संपीड़ित होते हैं। यह बहुत महत्वपूर्ण हो जाता है यदि आप स्ट्रिंग-प्रोसेसिंग समकक्ष, sscanf() के साथ डेटा के बड़े तारों को पार्स करना चाहते हैं।

आगे परीक्षण करने के लिए एक अच्छा व्यायाम कुछ इस तरह होगा: की जाँच करें और दोनों सही ढंग से और प्रारूप गलत सांत्वना दी इनपुट (यानी प्रदान करने के बाद देखते हैं कि इन पूर्णांकों का मान हैं बाद में

#include<stdio.h> 

int main(void) 
{ 
    int a=0,b=0,c=0; 

    printf("Enter values for A, B, C, in the format: \"A B - C\"\n"); 
    scanf("%d %d - %d", &a, &b, &c); 

    printf("Values: A:%d, B:%d, C:%d\n", a, b, c); 
} 

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

Enter values for A, B, C, in the format: "A B - C" 
1 2 3 
Values: A:1, B:2, C:0 

Enter values for A, B, C, in the format: "A B - C" 
1 2 - 3 
Values: A:1, B:2, C:3 

अब, एक पिछले रन पर विचार करें: आप देखेंगे कि scanf() एकल वर्ण के लिए कॉम्पैक्ट कई लगातार खाली स्थान के पात्रों, इसलिए क्यों इन अंतिम रन वास्तव में सफल होता है:

Enter values for A, B, C, in the format: "A B - C" 
1 2 - 3 
Values: A:1, B:2, C:3 

Enter values for A, B, C, in the format: "A B - C" 
1  2   -      3 
Values: A:1, B:2, C:3 
+1

-1: इन उदाहरणों में प्रारूप तारों में सभी रिक्त स्थान पूरी तरह से अप्रासंगिक हैं और परिणामों में कोई बदलाव नहीं होने के कारण हटाया जा सकता है, इसलिए यह वास्तव में प्रश्न का उत्तर नहीं देता है, जो प्रारूप स्ट्रिंग में पिछली जगह के बारे में है। .. –

+1

यह संक्षेप में बताता है कि व्हाइटस्पेस कैरेक्टर एक-दूसरे में कितने अलग हैं, और इस विशेष उदाहरण में पिछली सफेद जगह का परिणाम थोड़ा नतीजा है। यह भी वर्णन करता है कि प्रारूप स्ट्रिंग अपेक्षित व्हाइटसाइट स्पेस और गैर-व्हाइटस्पेस के पैटर्न को अनिवार्य रूप से कैसे कम करती है, और प्रारूप पैटर्न से विचलित होने पर निर्भर करता है कि कुछ या सभी लक्ष्य चरों पर मूल्यों का असाइनमेंट कैसे हो सकता है। मुझे नहीं लगता कि यह जरूरी था। – DevNull

+1

कोड को 'scanf() 'से वापसी मान रिकॉर्ड और रिपोर्ट करना चाहिए। इससे पता चलता है कि कितने मूल्य निर्धारित किए गए हैं। एक प्रारूप स्ट्रिंग में पीछे की सफेद जगह इंटरैक्टिव इनपुट के साथ "थोड़ा विवेक" नहीं है। इसका मतलब है कि इनपुट पूर्ण होने से पहले उपयोगकर्ता को सफेद स्थान (और नई लाइन सफेद जगह है) के अलावा एक वर्ण टाइप करना होगा। –

4

में एक खाली स्थान के चरित्र अपने scanf प्रारूप isspace द्वारा वर्णित अनुसार किसी भी प्रकार के व्हाइटस्पेस वर्णों से मेल खाता है। तो यदि आपके पास रिक्त स्थान, न्यूलाइन, टैबलेटर्स या किसी अन्य व्हाइटस्पेस कैरेक्टर हैं तो इसे वापस आने से पहले scanf तक भी उपभोग किया जाएगा।

+0

यह कुंजी बिंदु स्पष्ट नहीं करता है - कि 'स्कैनफ()' तब तक वापस नहीं आएगा जब तक कि सफेद स्थान नहीं है।बदले में, इसका मतलब है कि आपको अनुमान लगाना होगा कि कार्यक्रम आगे क्या पूछने जा रहा है और वर्तमान इनपुट पूरा होने से पहले अगला मान दर्ज करें। (यदि आप अगले अगले मूल्य में प्रवेश नहीं करते हैं, तो आपको और समस्याएं मिलेंगी; अजीब एक चरित्र (और टर्मिनल से पहले की जाने वाली नई लाइन प्रोग्राम को चरित्र भेजती है) को अगले क्षेत्र के रूप में व्याख्या किया जाएगा। इंटरैक्टिव प्रारूपों में रिक्त स्थान सख्त हैं! –

6

एक प्रारूप स्ट्रिंग में एक सफेद-स्पेस कैरेक्टर (स्पेस, न्यूलाइन, क्षैतिज और लंबवत टैब) इनपुट में किसी भी सफेद-स्पेस वर्णों से मेल खाता है।
अपने पहले मामले में

scanf("%d ",&j); 

जब यह सफेद-अंतरिक्ष चार (WSC) का सामना करना पड़ता ' ' तो यह सब सफेद रिक्त स्थान इनपुट \n सहित उपयोगकर्ता द्वारा Enter दबा पर खा जाएगा और यह एक में प्रवेश करने की उम्मीद करेंगे गैर-डब्लूएससी इस मामले में आपका प्रोग्राम Ctrl + Z दबाकर समाप्त हो जाएगा।

+1

क्या यह वास्तव में एक पॉज़िक्स सिस्टम पर समाप्त हो जाएगा जहां वह आदेश शीर्ष प्रक्रिया पृष्ठभूमि करता है? – DevNull

+2

@ डोगबर्ट; सुनिश्चित नहीं है कि एमएस-विन के लिए: 'Ctrl + D' – haccks

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