2012-08-14 22 views
7

मेरा कोड यहां है। मैं इसे टर्मिनल के साथ उबंटू में चलाता हूं। जब मैं टाइप करता हूं (एक Ctrlडी) टर्मिनल में, प्रोग्राम बंद नहीं हुआ लेकिन मेरे इनपुट के लिए प्रतीक्षा करना जारी रखा।ctrl-d ने थोड़ी देर नहीं रुकी (getchar()! = EOF) लूप

Ctrlयूनिक्स में डी बराबर EOF के लिए नहीं है?

धन्यवाद।

#include<stdio.h> 

main() { 
    int d; 
    while(d=getchar()!=EOF) { 
     printf("\"getchar()!=EOF\" result is %d\n", d); 
     printf("EOF:%d\n", EOF); 
    } 
     printf("\"getchar()!=EOF\" result is %d\n", d); 
} 
+1

यह रिकर्सन नहीं है। जब तक आप इनपुट ईओएल नहीं करते हैं तो यह केवल एक अनंत लूप है। रिकर्सन = फ़ंक्शन स्वयं को सीधे या कुछ अन्य मध्यवर्ती चरणों के बाद कॉल कर रहा है। –

+0

संकलित कि जीसीसी के साथ, '^ डी' मारने से मेरे लिए लूप बंद कर दिया गया। –

+0

@ जोनलिन बस इनपुट^डी। यह मेरे लिए भी काम करता है। हालांकि, जब इनपुट (ए^डी) होता है; लूप बंद नहीं होता था। – Sam

उत्तर

11

ईओएफ एक चरित्र नहीं है। EOF एक मैक्रो है जो getchar() देता है जब यह इनपुट के अंत तक पहुंचता है या किसी प्रकार की त्रुटि का सामना करता है। ^D "एक ईओएफ चरित्र" नहीं है। लिनक्स के तहत क्या हो रहा है जब आप एक लाइन पर^डी को हिट करते हैं, यह है कि यह स्ट्रीम बंद कर देता है, और getchar() कॉल इनपुट के अंत तक पहुंचता है और EOF मैक्रो देता है। यदि आप लाइन के बीच में ^D टाइप करते हैं, तो स्ट्रीम बंद नहीं होती है, इसलिए getchar() वह मान लौटाता है जो इसे पढ़ता है और आपका लूप बाहर नहीं निकलता है।

बेहतर विवरण के लिए stdio section of the C faq देखें।

इसके अतिरिक्त:

आधुनिक प्रणालियों पर, यह एक फ़ाइल में संग्रहीत किसी भी वास्तविक अंत के फ़ाइल चरित्र को प्रतिबिंबित नहीं करता है; यह एक संकेत है कि कोई और पात्र उपलब्ध नहीं है।

+0

मैंने ध्यान से वेबसाइट पढ़ी। मेरी राय में, यदि मैं लाइन के बीच में कहीं भी '^ डी' टाइप करता हूं, तो बैश '^ डी' से निपटने वाला होगा। नतीजतन, सी प्रोग्राम को स्ट्रीम बंद करने के लिए एक आदेश नहीं मिला। यदि मैं एक पंक्ति में '^ डी' टाइप करता हूं, तो सी प्रोग्राम को सही कमांड मिल जाएगा। क्या मैं सही हू? – Sam

+1

@qingfeng यहां '^ डी' के बारे में कुछ और है: http://www.c-faq.com/stdio/eofval.html लेकिन हाँ, धारा तब तक बंद नहीं होगी जब तक कि यह एक लाइन पर न हो। यहां संक्षिप्त विवरण: http://stackoverflow.com/a/1516177/851273 –

+6

जब टर्मिनल कैनोलिक मोड में होता है, तो जब तक आप एंटर दबाते हैं तब तक लाइनें tty डिवाइस पर प्रसारित नहीं होती हैं। कॉन्फ़िगर किए गए ईओएफ कुंजी (डिफ़ॉल्ट रूप से^डी) को दबाकर डेटा को तत्काल प्रेषित किया जा सकता है और उपलब्ध वर्णों की संख्या के साथ वापस आने के लिए कोई भी 'read' प्रतीक्षा कर रहा है। यदि लाइन पर पहले से डेटा है, तो यह सामान्य, गैर-शून्य-लंबाई पढ़ने वाला होगा। यदि रेखा खाली है, तो इसके परिणामस्वरूप शून्य-लंबाई पढ़ा जाएगा, जो फाइल डिस्क्रिप्टर पर एंड-ऑफ-फ़ाइल स्थिति की * परिभाषा * है। इस प्रकार stdio परत इसे ईओएफ स्थिति के रूप में व्याख्या करेगा। –

6

जॉन लिन के ईओएफ के बारे में उत्तर के अलावा, मुझे यकीन नहीं है कि आपके द्वारा लिखे गए कोड का उद्देश्य आप चाहते हैं। आप को देखने के लिए मूल्य चर d में getchar से लौटे चाहते हैं, आप करने के लिए अपने while बयान बदलने की जरूरत:

while((d=getchar())!=EOF) { 

इसका कारण यह है असमानता ऑपरेटर काम की तुलना में अधिक पूर्वता है। तो, आपके कोड में, d हमेशा 0 या 1 होगा।

+0

आप बहुत दयालु होने के लिए बहुत दयालु हैं। लेकिन मैं सिर्फ यह सत्यापित करना चाहता हूं कि अभिव्यक्ति 'd = getchar()! = EOF' 0 या 1. – Sam

+0

@ सैम: आप यह स्पष्ट कर सकते हैं कि आप तुलना करके तुलना का परिणाम असाइन कर रहे हैं: 'while ((d = (getchar()! = ईओएफ))! = 0) 'या 'के रूप में ((डी = (getchar()! = ईओएफ))' ताकि संकलक आप पर चेतावनी फेंक नहीं होगा। अधिक आम विकल्प 'जबकि ((डी = getchar())! = ईओएफ) 'जो' getchar() '' d' के परिणाम को निर्दिष्ट करता है और फिर इसे ईओएफ के साथ तुलना करता है। यह संकलक चेतावनियों से बचाता है। कई आधुनिक कंपाइलर्स आपके द्वारा लिखे गए कार्यों के लिए चेतावनी उत्पन्न करेंगे। –

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

  • कोई संबंधित समस्या नहीं^_^