2011-09-10 17 views
7

कोड:EOF समाप्त नहीं करता इनपुट धारा

#include <stdio.h> 
#define NEWLINE '\n' 
#define SPACE ' ' 

int main(void) 
{ 
    int ch; 
    int count = 0; 

    while((ch = getchar()) != EOF) 
    { 
     if(ch != NEWLINE && ch != SPACE) 
      count++; 
    } 
    printf("There are %d characters input\n" , count); 

    return 0; 
} 

प्रश्न:

  1. सब कुछ बस ठीक काम करता है, यह रिक्त स्थान और न्यू लाइन और उत्पादन पर ध्यान नहीं देगा स्क्रीन पर इनपुट अक्षरों की संख्या (इस कार्यक्रम में मैं केवल अल्पविराम, विस्मयादिबोधक चिह्न, संख्या या किसी भी प्रिंट करने योग्य विशेष प्रतीक चरित्र का इलाज करता हूं जैसे एम्पर्सेंड चरित्र के रूप में) जब मैंने ईओएफ सिमुलेशन को मारा जोहै।

  2. लेकिन जब मैं इस लाइन को प्रोग्राम में इनपुट करता हूं तो कुछ गड़बड़ होती है। उदाहरण के लिए मैं इसे इनपुट करता हूं: abcdefg^z, जिसका अर्थ है कि मैं ^z के समान लाइन पर पहले और उसके बाद कुछ वर्ण इनपुट करता हूं। कार्यक्रम को समाप्त करने और कुल पात्रों को मुद्रित करने के बजाय, कार्यक्रम इनपुट मांगना जारी रखेगा।

  3. ईओएफ टर्मिनल वर्ण इनपुट केवल तभी काम करता है जब मैं एक पंक्ति पर ^z निर्दिष्ट करता हूं या ऐसा कर रहा हूं: ^zabvcjdjsjsj। ये क्यों हो रहा है?

उत्तर

14

यह लगभग हर टर्मिनल ड्राइवर में सच है। लिनक्स का उपयोग करके आपको वही व्यवहार मिल जाएगा।

आपका प्रोग्राम वास्तव में लूप को निष्पादित नहीं कर रहा है जब तक कि \n या ^z लाइन के अंत में आपके द्वारा दर्ज नहीं किया गया है। टर्मिनल ड्राइवर इनपुट को बफर कर रहा है और इसे तब तक आपकी प्रक्रिया में नहीं भेजा गया है जब तक ऐसा नहीं होता है।

एक पंक्ति के अंत में, मार ^z (या ^d लिनक्स पर) नहीं कारण EOF भेजने के लिए टर्मिनल ड्राइवर करता है। यह केवल बफर को आपकी प्रक्रिया में फ्लश करता है (\n के साथ)।

लाइन की शुरुआत में ^z (या लिनक्स पर ^d) मारना टर्मिनल द्वारा "मैं ईओएफ सिग्नल करना चाहता हूं" के रूप में व्याख्या किया जाता है।

अगर आप अपने पाश अंदर निम्नलिखित जोड़ें आप इस व्यवहार को देख सकते हैं:

printf("%d\n",ch); 

अपने कार्यक्रम चलाएँ:

$ ./test 
abc      <- type "abc" and hit "enter" 
97 
98 
99 
10 
abc97     <- type "abc" and hit "^z" 
98 
99 

बेहतर यह समझने के लिए, आप को एहसास है कि EOF एक नहीं है है चरित्र। ^z एक उपयोगकर्ता आदेश टर्मिनल के लिए है। चूंकि टर्मिनल उपयोगकर्ता इनपुट लेने और इसे प्रक्रियाओं में पास करने के लिए ज़िम्मेदार है, इसलिए यह मुश्किल हो जाता है और इस प्रकार भ्रम हो जाता है।

इसे देखने का एक तरीका ^v पर क्लिक करके ^z को अपने प्रोग्राम में इनपुट के रूप में मार रहा है।

^v एक और टर्मिनल कमांड है जो टर्मिनल को बताता है, "अरे, अगली चीज़ जो मैं टाइप करता हूं - टर्मिनल कमांड के रूप में इसकी व्याख्या नहीं करता; इसे 'इनपुट के बजाय' प्रक्रिया में पास करें।

4

^Z केवल कार्यक्रम जब यह एक लाइन के शुरू में लिखा गया हो करने के लिए एक EOF संकेत करने के लिए कंसोल से अनुवाद किया है। यह वही तरीका है जो विंडोज कंसोल काम करता है। इस व्यवहार के लिए कोई "कामकाज" नहीं है जिसे मैं जानता हूं।

+0

फिर क्यों^z को एक वर्ण के रूप में गिना नहीं जाता है जब मैं इसे एक पंक्ति में विशेषताओं की धारा के बाद रखता हूं? उदाहरण के लिए "abcdefg^z" केवल मुझे वापस लौटाता है "इनपुट के बाद 8 के बजाय 7 अक्षर inpit"^जेड उस लाइन के बाद। – caramel1995

+0

@ कारमेल 23: मेरा मानना ​​है कि विंडोज कंसोल बस इसे अनदेखा करता है और प्रोग्राम को चलाने के लिए एक चरित्र पास नहीं करता है। मुझे नहीं पता कि ऐसा क्यों होता है। –

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