2011-12-14 47 views
5

बताएं यह कोड के & आर से आता है। मैंने इसे कई बार पढ़ा है, लेकिन यह अभी भी मेरी समझ से बचने लगता है।कृपया इस उदाहरण सी कोड

#define BUFSIZE 100 

char buf[BUFSIZE]; 
int bufp = 0; 

int getch(void) 
{ 
     return(bufp>0)?buf[--bufp]:getchar(); 
} 

int ungetch(int c) 
{ 
     if(bufp>=BUFSIZE) 
      printf("too many characters"); 
     else buf[bufp++]=c; 
} 

इन दोनों कार्यों के प्रयोजन है, तो कश्मीर & आर कहते हैं, बहुत ज्यादा इनपुट पढ़ने से एक कार्यक्रम को रोकने के लिए है। यानी इस कोड के बिना एक फ़ंक्शन यह निर्धारित करने में सक्षम नहीं हो सकता है कि इसे पहले पढ़ने के बिना पर्याप्त डेटा पढ़ा गया है। लेकिन मुझे समझ में नहीं आता कि यह कैसे काम करता है।

उदाहरण के लिए, getch() पर विचार करें। जहाँ तक मुझे इस रूप में देख सकते हैं चरणों का यह लेता है: bufp 0.

  • से अधिक है

    1. जांच कर लें कि यदि ऐसा है तो फिर से buf चार मान [- bufp]।
    2. अन्य getchar() वापस लौटें।

    मैं एक और विशिष्ट सवाल पूछना चाहता हूं, लेकिन मुझे सचमुच यह नहीं पता कि यह कोड प्राप्त करने के लिए क्या उद्देश्य प्राप्त करता है, इसलिए मेरा प्रश्न है: (ए) उद्देश्य और (बी) तर्क क्या है इस कोड का?

    अग्रिम धन्यवाद।

    नोट: किसी भी कश्मीर & आर प्रशंसकों के लिए, इस कोड पेज 79 पर पाया जा सकता (आपके संस्करण के आधार पर, मुझे लगता है)

  • +0

    'ungetch' के अंदर परीक्षण में शायद इसकी स्थिति में 'bufp'' printf' शामिल नहीं होना चाहिए। मुझे लगता है कि यह एक टाइपो है। –

    +0

    मेरे पास हाथ में के एंड आर नहीं है, लेकिन मुझे लगता है कि अगर अनजान में, अगर शर्त 'bufp> = BUFSIZE' – kol

    +0

    होनी चाहिए, शायद मेरी गलती। सोमेन ने इसे अभी तय कर दिया है, इसलिए मुझे याद नहीं आया कि मैंने जो मूल रूप से टाइप किया है। –

    उत्तर

    9

    (क) इस कोड के प्रयोजन के एक चरित्र को पढ़ने के लिए सक्षम होने के लिए है और उसके बाद यह "अन-पढ़ा" जाता है अगर यह पता चला कि आप गलती से एक चरित्र को बहुत अधिक पढ़ते हैं (अधिकतम 100 वर्णों के साथ "अन-पढ़ा")। यह देखने के लिए पार्सर्स में उपयोगी है।

    (बी) getchbuf से पढ़ता है यदि इसमें सामग्री है, bufp>0 द्वारा इंगित किया गया है। यदि buf खाली है, तो यह getchar पर कॉल करता है। ध्यान दें कि यह buf का उपयोग स्टैक के रूप में करता है: यह इसे दाएं से बाएं से पढ़ता है।

    ungetch स्टैक buf पर एक चरित्र को धक्का नहीं देता है यह देखने के लिए कि क्या स्टैक भरा हुआ है या नहीं।

    +0

    लेकिन माना जाता है कि ungetch नहीं कहा जाता है, तो getch हमेशा getchar() वापस आ जाएगा, क्योंकि bufp अनिश्चित काल तक शून्य होगा। मैं इस भाग को समझ नहीं पा रहा हूं। –

    +0

    @JJG: यह सही है, अगर आप कभी भी 'ungetch' नहीं कहते हैं, तो आपको बफर की आवश्यकता नहीं होगी और हमेशा 'getchar' से ताजा इनपुट प्राप्त होगा। –

    1

    कोड वास्तव में "बहुत अधिक इनपुट पढ़ने" के लिए नहीं है, इसके बजाए आप कर सकते हैं अक्षर पहले से ही पढ़ सकते हैं।

    उदाहरण के लिए, आप getch के साथ एक वर्ण पढ़ते हैं, देखें कि यह एक पत्र है, इसे ungetch के साथ वापस रखें और लूप में सभी अक्षरों को पढ़ें। यह भविष्यवाणी करने का एक तरीका है कि अगला चरित्र क्या होगा।

    1

    कोड का यह ब्लॉक उन कार्यक्रमों के उपयोग के लिए है जो स्ट्रीम से जो पढ़ते हैं उसके आधार पर निर्णय लेते हैं। कभी-कभी ऐसे कार्यक्रमों को वास्तव में इनपुट का उपभोग किए बिना स्ट्रीम से कुछ चरित्रों को देखने की आवश्यकता होती है। उदाहरण के लिए, यदि आपका इनपुट abcde12xy789 जैसा दिखता है और आपको इसे abcde, 12, xy, 789 (यानी लगातार अंकों के समूहों से लगातार अक्षरों के अलग-अलग समूह) में विभाजित करना होगा, तो आप नहीं जानते कि आप अक्षरों के समूह के अंत तक पहुंच गए हैं जब तक आप एक अंक नहीं देखते हैं। हालांकि, आप उस अंक को उस समय उपभोग नहीं करना चाहते हैं जब आप इसे देखते हैं: आपको केवल यह जानना है कि अक्षरों का समूह समाप्त हो रहा है; आपको उस अंक को "वापस" रखने का एक तरीका चाहिए।एक ungetch इस स्थिति में काम में आता है: एक बार जब आप अक्षरों के समूह के बाद अंक देखते हैं, तो आप ungetch पर कॉल करके अंक वापस डाल देते हैं। आपका अगला पुनरावृत्ति उसी अंक को उसी getch तंत्र के माध्यम से वापस ले जाएगा, जो आपको पढ़ने वाले चरित्र को संरक्षित करने की आवश्यकता को छोड़ देता है लेकिन उपभोग नहीं करता है।

    0
      1. यहां दिखाया गया दूसरा विचार भी एक बहुत ही प्राचीन I/O स्टैक मैंगमेंट सिस्टम के रूप में भी जाना जा सकता है और फ़ंक्शन getch() और ungetch() के कार्यान्वयन को देता है।
      2. एक कदम आगे जाने के लिए, मान लें कि आप एक ऑपरेटिंग सिस्टम डिज़ाइन करना चाहते हैं, आप सभी कीस्ट्रोक को संग्रहीत करने वाली मेमोरी को कैसे प्रबंधित कर सकते हैं?

    यह उपरोक्त कोड स्निपेट द्वारा हल किया गया है। इस अवधारणा का विस्तार फ़ाइल हैंडलिंग में विशेष रूप से फ़ाइलों को संपादित करने में किया जाता है। उस मामले में getchar() का उपयोग करने के बजाय मानक इनपुट से इनपुट लेने के लिए उपयोग किया जाता है, फ़ाइल इनपुट के स्रोत के रूप में प्रयोग किया जाता है।