2012-12-21 9 views
19

हम जानते हैं कि stdin डिफ़ॉल्ट रूप से, एक buffered इनपुट है; इस बात का सबूत है, तंत्र stdin पर "डेटा छोड़" में से किसी के उपयोग में है इस तरह के रूप में scanf():क्या स्टडीन बफर पर नजर डालने के लिए वैसे भी है?

int main() 
{ 
    char c[10] = {'\0'}; 
    scanf("%9s", c); 
    printf("%s, and left is: %d\n", c, getchar()); 
    return 0; 
} 

./a.out
हैलो
नमस्ते, और बाईं 10

है

10 निश्चित रूप से न्यू लाइन किया जा रहा है ...

मैं हमेशा से उत्सुक किया गया है, वहाँ वैसे भी "झांकना" करने के लिए है stdin बफर जो कुछ भी वहां रह सकता है उसे हटाए बिना?

संपादित
एक बेहतर उदाहरण हो सकता है:

scanf("%9[^.]", c); 
"at.ct" की एक इनपुट के साथ

, अब मैं "डाटा" (ct\n) stdin पर छोड़ दिया, न सिर्फ एक नई पंक्ति की है।

+1

आप peeking के बाद 'ungetc() 'कर सकते हैं। काफी है? –

+0

@DanielFischer - मुझे लगता है कि यह बुरा नहीं है ... क्या होगा अगर वर्णों का पूरा समूह छोड़ा गया हो? क्या मैं stdin पर छोड़े गए डेटा की लंबाई जान सकता हूं? या मैं एक अक्षर फिर से ungetc() 'सकता था? – Mike

+0

"पुशबैक का एक चरित्र गारंटीकृत है। अगर उस स्ट्रीम पर 'ungetc' फ़ंक्शन को एक ही स्ट्रीम पर कई बार बार-बार पढ़ने या फ़ाइल पोजिशनिंग ऑपरेशन के बिना बुलाया जाता है, तो ऑपरेशन विफल हो सकता है।" आमतौर पर, आप एक से अधिक 'ungetc' कर सकते हैं, लेकिन केवल एक की गारंटी है। –

उत्तर

11

पोर्टेबल, आप getchar() के साथ इनपुट स्ट्रीम में अगला अक्षर प्राप्त कर सकते हैं और फिर उसे ungetc() के साथ वापस धक्का दे सकते हैं, जिसके परिणामस्वरूप राज्य को चरित्र से हटाया नहीं गया था।

ungetc समारोह चरित्र c (एक unsigned char करने के लिए परिवर्तित) द्वारा निर्दिष्ट पीठ पर इनपुट धारा धारा के द्वारा की ओर इशारा किया धकेलती है। पंप-बैक कैरेक्टर को उस धारा पर उनके धक्का के विपरीत क्रम में बाद में पढ़ा जाएगा।

मानक द्वारा पुशबैक की केवल एक विशेषता की गारंटी है, लेकिन आमतौर पर, आप और अधिक धक्का दे सकते हैं।

जैसा कि अन्य उत्तरों में उल्लेख किया गया है। ,

तो buf एक अशक्त सूचक नहीं है सरणी यह ​​की ओर इशारा करता: वहाँ टिप्पणी नहीं, व्यवहार में, आप लगभग निश्चित रूप से बफर में झांक सकते अगर आप, setvbuf साथ अपने स्वयं के बफर प्रदान हालांकि कि समस्याओं के बिना नहीं है सकते हैं एक बफर setvbuf समारोह

कि संभावना है कि प्रदान की जाती बफर सब पर नहीं किया जा सकता छोड़ देता है द्वारा आवंटित की बजाय प्रयोग किया जा सकता है।

किसी भी समय सरणी की सामग्री अनिश्चित हैं।

इसका मतलब है कि आपको गारंटी नहीं है कि बफर की सामग्री वास्तविक इनपुट को प्रतिबिंबित करती है (और अगर यह पिक्य हो तो स्वचालित भंडारण अवधि होने पर बफर अनिर्धारित व्यवहार का उपयोग करता है)।

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

+1

जब कोई इनपुट पढ़ने के लिए इनपुट बफर खाली ब्लॉक होता है तो 'getchar' नहीं कर रहा है? –

+0

वास्तव में, यह होगा। हालांकि, बफर खाली है या नहीं, यह जांचने के लिए मुझे एक पोर्टेबल तरीके से अवगत नहीं है। –

5

आप अपने स्वयं के बफर को setvbuf पर स्टडीन पर सेट कर सकते हैं, और जब भी चाहें वहां देख सकते हैं।

+0

वह 'ungetc' के साथ कैसे बातचीत करेगा? मुझे लगता है कि 'ungetc'ed चरित्र किसी अन्य चर में संग्रहीत है। साथ ही, आप कैसे जानेंगे कि बफर का कौन सा हिस्सा पढ़ा जाता है और क्या बचा है? – Shahbaz

+0

'setvbuf() फ़ंक्शन का stdout, stdin, या stderr पर कोई प्रभाव नहीं पड़ता है।' जो मैंने पढ़ा है। क्या आपके पास एक कामकाजी उदाहरण है? – Mike

+0

@ माइक यह विंडोज़ पर काम करता प्रतीत होता है। अपेक्षित के रूप में 'ungetc' काम करता है। पढ़ने/बाएं पॉज़ का ट्रैक रखने के तरीके के बारे में पूरी तरह से सुनिश्चित नहीं है। लेकिन अगर बफ नई लाइन वाली है, तो यह आसान होगा। – nullpotent

3

आप इसे बदले बिना stdin बफर को देखने के लिए चाहते हैं, आप के साथ एक setbuf एक और बफर उपयोग करने के लिए, एक सरणी का उपयोग कर आप उपयोग कर सकते हैं यह बता सकते हैं:

char buffer[BUFSIZ]; 

if (setbuf(stdin, buffer) != 0) 
    // error 

getchar(); 

printf("%15s\n", buffer); 

यह जाने आप से कुछ अधिक देखने ungetc, लेकिन मुझे नहीं लगता कि आप एक पोर्टेबल तरीके से आगे जा सकते हैं।

वास्तव में इस कानूनी है, लेकिन नहीं setvbuf के बारे में यह से उद्धृत, मानक के लिए सही है (setbuf समान व्यवहार किया है):

किसी भी समय सरणी की सामग्री को अनिश्चित हैं।

तो यदि आप पूर्ण पोर्टेबिलिटी और मानक अनुपालन की तलाश में हैं तो यह आवश्यक नहीं है, लेकिन मैं कल्पना नहीं कर सकता कि बफर में क्या अपेक्षित नहीं होना चाहिए। हालांकि, ऐसा लगता है कि यह मेरे कंप्यूटर पर काम करता है।

सावधान रहें कि आपको कम से कम BUFSIZ वर्णों को setbuf पर एक सरणी प्रदान करना है, और आपको इससे पहले स्ट्रीम पर कोई I/O ऑपरेशन नहीं करना चाहिए। यदि आपको अधिक लचीलापन की आवश्यकता है, तो setvbuf पर एक नज़र डालें।

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