2012-06-21 10 views
5

मैं इस समस्या से आया जब मैं यह जांचना चाहता हूं कि इनपुट क्या है। यदि मैं सफलतापूर्वक एक संख्या इनपुट करता हूं तो स्कैनफ़ फ़ंक्शन 1 वापस आ जाएगा।क्या होता है जब आप 12ab जैसे स्कैनफ ("% d", और argu) इनपुट करते हैं?

int argu; 
while(scanf("%d",&argu)!=1){ 
    printf("Please input a number!\n"); 
} 

लेकिन जब मैं यह करने के लिए एबीसीडी जैसे इनपुट बातें, पाश हमेशा के लिए जाना होगा और शीघ्र के लिए बंद नहीं: तो यहाँ मैं क्या लिखा है।

मैंने इसे ऑनलाइन देखा और पाया कि इसमें कैश के साथ कुछ करना है और मुझे इसे साफ़ करने की आवश्यकता है ताकि स्कैनफ को नया डेटा मिल सके। तो मैंने fflush की कोशिश की लेकिन यह काम नहीं किया। फिर जब 'एबीसीडी' की तरह मैं इनपुट बातें यह अच्छी तरह से काम

int argu,j; 
while(scanf("%d",&argu)!=1){ 
    printf("Please input a number!\n"); 
    while((j=getchar())!='\n' && j != '\n'); 
} 

और यह मेरे इनपुट के लिए संकेत:

तो मैं में देखा। लेकिन जब मैं '12ab' जैसी चीजें इनपुट करता हूं, तो यह फिर से काम नहीं करेगा।

तो क्या कोई तरीका है कि मैं स्कैनफ़ ("% d", & argu) के लिए इनपुट की जांच कर सकता हूं वास्तव में एक संख्या है और यदि कोई अन्य इनपुट के लिए संकेत नहीं है?

संपादित:

मैं जवाब को देखा और while(*eptr != '\n') का उपयोग करके मेरी समस्या हल।

ध्यान दें कि fgets फ़ंक्शन वास्तव में सरणी में '\ n' पढ़ता है और fget नहीं करता है। तो सावधान रहें।

उत्तर

4

fgets() का उपयोग करके, और फिर इनपुट स्ट्रीम से "फ्लाई पर" पार्स करने की कोशिश करने के बजाय, एक पूर्ण लाइन को पढ़ने के लिए बेहतर है।

गैर-मान्य इनपुट को इस तरह से अनदेखा करना आसान है।

fgets() और फिर strtol() का उपयोग किसी संख्या में कनवर्ट करने के लिए करें, इससे यह देखने में आसान लगेगा कि संख्या के बाद पीछे पीछे डेटा है या नहीं।

उदाहरण के लिए:

char line[128]; 

while(fgets(line, sizeof line, stdin) != NULL) 
{ 
    char *eptr = NULL; 
    long v = strtol(line, &eptr, 10); 
    if(eptr == NULL || !isspace(*eptr)) 
    { 
    printf("Invalid input: %s", line); 
    continue; 
    } 
    /* Put desired processing code here. */ 
} 
+0

fgets (s, 10, stdin) जैसे कोड का उपयोग करें? – Gnijuohz

+0

धन्यवाद! मुझे स्ट्रेटोल नहीं पता था। बहुत कुछ सीखा! – Gnijuohz

+0

क्षमा करें, क्या आप 'if (eptr == NULL ||! Isspace (* eptr)) समझा सकते हैं? आपके द्वारा दिए गए कोड का उपयोग करते समय, '12 34 'जैसे इनपुट स्वीकार किए जाते हैं लेकिन वे नहीं होना चाहिए। जब मैं '1234' इनपुट करता हूं तो क्या एपीआरआर इंगित करेगा और '12ab' और '12 34 'के बारे में कैसे होगा? – Gnijuohz

1

मैं एक स्ट्रिंग के रूप इनपुट मिलता है और यह गैर-न्यूमेरिक वर्ण के लिए जाँच करने के लिए सुझाव देगा। यदि इनपुट sscanf(str,"%d",&i); या अन्यथा डायप्ले त्रुटि से स्ट्रिंग को स्ट्रिंग में परिवर्तित कर देता है।

1

लूप के अंदर बस स्कैनफ ("% * [^ \ n] \ n") को कॉल करें, और यह "कैश" को त्याग देगा।

+0

मैंने कोशिश की। यह काम नहीं किया। – Gnijuohz

+0

ऐसा इसलिए है क्योंकि इनपुट स्ट्रीम के लिए 'fflush' के लिए व्यवहार परिभाषित नहीं किया गया है। [सी भाषा मानक] देखें (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf), सेक्शन 7.1 9.5.2, अनुच्छेद 2. –

+0

आप दोनों सही हैं। आशा है कि संपादन, हालांकि, अब सही है (मानक के आधार पर)। – Spidey

2

लेकिन जब मैं इसे एबीसीडी जैसी चीजें इनपुट करता हूं, तो लूप हमेशा के लिए चलेगा और तुरंत संकेत नहीं देगा।

ऐसा इसलिए है क्योंकि scanf एक ऐसे चरित्र से मुठभेड़ करता है जो रूपांतरण विनिर्देश से मेल नहीं खाता है, तो यह इनपुट स्ट्रीम में छोड़ देता है। असल में, क्या हो रहा है कि scanf इनपुट स्ट्रीम से वर्ण a पढ़ता है, यह निर्धारित करता है कि यह %d रूपांतरण विनिर्देशक के लिए मान्य मिलान नहीं है, और फिर इसे इनपुट स्ट्रीम पर वापस धक्का देता है। अगली बार लूप के माध्यम से यह वही काम करता है। और फिर। और फिर। और फिर।

fflush एक अच्छा समाधान नहीं है, क्योंकि यह इनपुट धाराओं पर काम करने के लिए परिभाषित नहीं है।

इनपुट "12ab" के लिए, scanf पढ़ सकते हैं और "12" कनवर्ट करते हैं, इनपुट स्ट्रीम में "ab" छोड़ देगा।

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

char input[SIZE]; // assume SIZE is big enough for whatever input we get 
int value; 

if (fgets(input, sizeof input, stdin) != NULL) 
{ 
    char *chk; 
    int tmp = (int) strtol(input, &chk, 10); 
    if (isspace(*chk) || *chk == 0) 
    value = tmp; 
    else 
    printf("%s is not a valid integer string\n", input); 
} 

chk अंक: उदाहरण के लिए। यदि यह वर्ण व्हाइटस्पेस या 0 टर्मिनेटर नहीं है, तो इनपुट स्ट्रिंग मान्य पूर्णांक नहीं थी। यह "12ab" जैसे "abcd" जैसे इनपुट का पता लगाएगा और अस्वीकार करेगा।

scanf एक अच्छा समाधान है यदि आपको पता है कि आपका इनपुट हमेशा सही ढंग से गठित और अच्छी तरह से व्यवहार किया जा रहा है। यदि कोई मौका है कि आपका इनपुट अच्छी तरह से व्यवहार नहीं किया गया है, तो fgets का उपयोग करें और आवश्यकतानुसार रूपांतरित करें।

0

लूप के अंदर scanf("%*[^\n]\n") पर कॉल करें। यह कैश से जुड़े किसी भी चीज़ को त्यागने के लिए पर्याप्त होना चाहिए।

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

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