स्कैनफ () बफर में नई लाइन चार छोड़ देता है


93

मेरे पास निम्नलिखित कार्यक्रम हैं:

जैसा कि मैंने सी पुस्तक में पढ़ा है, लेखक का कहना है कि scanf()बफर में एक नई लाइन चरित्र को छोड़ दिया है, इसलिए, उपयोगकर्ता डेटा दर्ज करने के लिए प्रोग्राम लाइन 4 पर नहीं रुकता है, बल्कि यह सी 2 में नई लाइन के चरित्र को संग्रहीत करता है और अंदर जाता है पंक्ति 5।

क्या वह सही है?

हालाँकि, क्या यह केवल charडेटा प्रकारों के साथ होता है ? क्योंकि मैंने इस समस्या को intडेटा प्रकार 1, 2, 3 के साथ नहीं देखा था । क्या यह सही है?


कभी-कभी यह सुझाव दिया fflush(stdin)जाता है कि कॉल से पहले scanf()किसी एकल वर्ण के लिए उपयोग किया जा सकता है । कृपया उस विधि के लिए पेशेवरों और विपक्षों और विकल्पों की चर्चा के लिए प्रयोगfflush(stdin) करें (जो विंडोज पर काम करता है, अधिक या कम, और अधिकांश अन्य स्थानों पर काम नहीं करता है)।
जोनाथन लेफ्लर 3

क्या आप हमें बता सकते हैं कि आप किस पुस्तक का उल्लेख कर रहे हैं? '
सूर्या किरन

जवाबों:


82

scanf()समारोह स्किप के स्वचालित रूप से अग्रणी खाली स्थान के अक्षरों से अधिक अन्य रूपांतरण पार्स करने के लिए प्रयास करने से पहले। चरित्र प्रारूप (मुख्य रूप से %c; स्कैन सेट भी %[…]- और %n) अपवाद हैं; वे व्हॉट्सएप को स्किप नहीं करते हैं।

का प्रयोग करें " %c"वैकल्पिक सफेद स्थान को छोड़ने के लिए एक प्रमुख खाली साथ। एक scanf()प्रारूप स्ट्रिंग में अनुगामी रिक्त का उपयोग न करें ।

ध्यान दें कि यह अभी भी इनपुट स्ट्रीम में छोड़े गए किसी भी अनुगामी व्हाट्सएप का उपभोग नहीं करता है, यहां तक ​​कि एक पंक्ति के अंत तक भी नहीं, इसलिए यदि कोई उपयोग कर रहा है getchar()या fgets()उसी इनपुट स्ट्रीम से सावधान रहें । हम रूपांतरणों से पहले व्हॉट्सएप को छोड़ने के लिए केवल स्कैनफ़ प्राप्त कर रहे हैं , जैसे कि यह %dअन्य गैर-चरित्र रूपांतरणों के लिए करता है।


ध्यान दें कि गैर-व्हाट्सएप "निर्देश" ( POSIX स्कैनफ शब्दावली का उपयोग करने के लिए ) रूपांतरणों के अलावा, शाब्दिक पाठ की तरह व्हाट्सएप को scanf("order = %d", &order);भी नहीं छोड़ता है। शाब्दिक orderको पढ़ने के लिए अगले चरित्र से मेल खाना है।

तो आप शायद " order = %d"वहाँ चाहते हैं यदि आप पिछली पंक्ति से एक नई रेखा छोड़ना चाहते हैं, लेकिन फिर भी इस प्रश्न की तरह , एक निश्चित स्ट्रिंग पर शाब्दिक मिलान की आवश्यकता है ।


9
%c, %n, %[]3 निर्दिष्ट उम्मीदों कि प्रमुख खाली स्थान के उपभोग नहीं करते हैं।
chux - मोनिका

@chux तो अन्य मामलों में करता है, स्कैनफ बफर में से पहले सभी व्हाट्सएप को साफ करता है या उन्हें इनपुट के लिए अनदेखा करता है लेकिन वे अभी भी वहां हैं?
सूरज जैन

@ सुरजजैन हाँ,
chux -

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

32

का उपयोग करें scanf(" %c", &c2);। इससे आपकी समस्या दूर हो जाएगी।


8

एक अन्य विकल्प (जो मुझे यहां से मिला ) असाइनमेंट-सुपरशन विकल्प का उपयोग करके नई पंक्ति को पढ़ना और छोड़ना है । ऐसा करने के लिए, हम सिर्फ एक प्रारूप के बीच एक चरित्र के साथ पढ़ने के लिए डालते हैं %और c:

scanf इसके बाद अगला चार्ट (जो कि नई लाइन है) पढ़ेगा, लेकिन इसे किसी भी पॉइंटर पर न भेजें।

हालांकि, अंत में, मैं अक्सर पूछे जाने वाले प्रश्न का अंतिम विकल्प दूंगा :

या, अपनी आवश्यकताओं के आधार पर, आप स्कैनफ़ () / गेटचार () के बारे में भी भूल सकते हैं, उपयोगकर्ता से पाठ की एक पंक्ति प्राप्त करने और इसे स्वयं पार्स करने के लिए () का उपयोग करें।


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

4

getchar()दूसरा फोन करने से पहले उपयोग करें scanf()


1
यह काम करता है, उदाहरण के लिए, उपयोगकर्ता ने कुछ और नहीं लिखा है - उदाहरण के लिए, रिक्त स्थान। लेकिन यह एक लूप जितना अच्छा नहीं है जो अगली नईलाइन पर स्कैन करता है: int c; while ((c = getchar()) != EOF && c != '\n') ;(एक टिप्पणी में नहीं होने पर तीन पंक्तियों पर लिखा गया)। यह अक्सर पर्याप्त होता है; यह मूर्खतापूर्ण नहीं है (और आपको याद रखना होगा कि मूर्ख दुर्घटनाग्रस्त चीजों के बारे में बहुत चतुर हैं)।
जोनाथन लेफ्लर 3
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.