2013-11-29 4 views
5

read-line और read-char दोनों की आवश्यकता होती है आप कुछ लिखने के बाद Enter कुंजी दबाएं। क्या आम लिस्प में कोई तंत्र है जो प्रोग्राम को एंटर दबाए जाने के अतिरिक्त चरण की आवश्यकता के बिना तत्काल किसी भी चरित्र के प्रेस पर जारी रखने की अनुमति देगा?दर्ज बटन की आवश्यकता के बिना एक चरित्र पढ़ना दबाया

मैं एक कार्यक्रम के लिए एक त्वरित, गतिशील पाठ इनपुट इंटरफेस के निर्माण के लिए तो उपयोगकर्ताओं को जल्दी से आसपास नेविगेट और नंबर या परदे पर मेनू के लिए इसी पत्र दबाकर अलग अलग बातें कर सकते हैं कोशिश कर रहा हूँ। एंटर कुंजी के सभी अतिरिक्त प्रेस वर्कफ़्लो को गंभीरता से बाधित करते हैं। यह एक प्रॉम्प्ट से पूछताछ के "वाई/एन" प्रकार के समान होगा, जहां बस "y" या "n" दबाकर पर्याप्त है।

मैं SBCL उपयोग कर रहा हूँ, कि अगर एक फर्क नहीं पड़ता। शायद यह कार्यान्वयन विशिष्ट है, मैं this page पर दोनों उदाहरण की कोशिश की और यह काम नहीं करता (मैं अभी भी Enter दबाने की आवश्यकता); यहां पहला है:

(defun y-or-n() 
(clear-input *standard-input*) 
(loop as dum = (format t "Y or N for yes or no: ") 
    as c = (read-char) 
    as q = (and (not (equal C#\n)) (not (equal C#\y))) 
    when q do (format t "~%Need Y or N~%") 
    unless q return (if (equal C#\y) 'yes 'no))) 

उत्तर

8

read-char आपको प्रवेश करने की आवश्यकता नहीं है। उदाहरण के लिए,

CL-USER> (with-input-from-string (x "hello") 
      (print (read-char x))) 

#\h 

इसी प्रकार, यदि आप कमांड लाइन से SBCL में कुछ इनपुट भेजने के लिए, यह एक नई पंक्ति के बिना पढ़ा जाएगा:

$ echo -n hello | sbcl --eval "(print (read-char))" 
… 
#\h 

पढ़ने और मुद्रण #\h के बाद, SBCL ello देखा :

* 
debugger invoked on a UNBOUND-VARIABLE in thread #<THREAD 
                "initial thread" RUNNING 
                {1002979011}>: 
    The variable ELLO is unbound. 

मुझे लगता है कि यह पुष्टि करते हैं कि ऐसा नहीं है कि read-char एक की जरूरत के लिए पर्याप्त है न्यू लाइन, बल्कि इनपुट के बफरिंग समस्या यह है कि। मुझे लगता है कि यह एक ही समस्या (या गैर समस्या) है कि 2008 से एक comp.lang.lisp सूत्र में वर्णित है: Re: A problem with read-char। उपयोगकर्ता पूछते हैं:

यह С में getch की तरह पढ़-चार व्यवहार बनाने के लिए जब इंटरैक्टिव धारा (मानक इनपुट) के साथ काम कर रहे संभव है? एसबीसीएल रीड-चार में आरईपीएल से अनहैंग करने के लिए "एंटर" कुंजी चाहता है, सी गेटचर में तुरंत कीबोर्ड पर उपयोगकर्ता कुंजी कुंजी के बाद लौटाता है। शायद कोड चलाने के लिए संभव है जो प्रत्यक्ष कंसोल एक्सेस के साथ रीड-char का उपयोग करता है, एक तरफ आरईपीएल?

चार प्रतिक्रियाएं थीं (thread index उन सभी को प्राप्त करने के लिए देखें)। ये क्यों बताते हैं यह व्यवहार देखा जाता है (उदाहरण के लिए, लिस्प प्रक्रिया को टर्मिनल से कच्चे इनपुट नहीं मिल रहे हैं, बल्कि इनपुट buffered)। Pascal Bourguignon described the problem, और एक तरह CLISP के साथ इस संभाल करने के लिए (लेकिन सभी कि ज्यादा मदद, एक तरफ सामान्य अच्छी सलाह से प्रदान नहीं करता है) SBCL में इस के आसपास काम कर के बारे में:

अंतर शाप में टर्मिनल डालता है है कच्चे मोड को को एक बार कीबोर्ड से अक्षर प्राप्त करने के लिए को पके हुए मोड में टर्मिनल छोड़ने के बजाय सक्षम किया जा सकता है, जहां यूनिक्स ड्राइवर लाइनों और अन्य niceties के बीच बैकस्पेस हैंडल करता है।

...

अब, मैं SBCL के बारे में पता नहीं है, (SBCL के मैनुअल की जाँच)। मेरे पास केवल है जो मेरे गीलेवेयर में लोड किए गए सीएलआईएसपी के कार्यान्वयन नोट्स हैं। सीएलआईएसपी में आप EXT का उपयोग कर सकते हैं: कीबोर्ड के साथ मैक्रो (जबकि बुनियादी आउटपुट फीचर्स श्राप के पैकेज द्वारा प्रदान की जाती हैं)।

मैं एक बार लिखा था कि एक आवेदन चाहता था कि एक वर्ण प्रतिक्रिया टाइप करने के लिए सक्षम होने के लिए के लिए CMUCL के लिए निम्नलिखित:

Rob Warnock's response कि या SBCL के लिए काम नहीं कर सकते हो सकता है CMUCL के लिए कुछ वैकल्पिक हल कोड शामिल

(defun read-char-no-echo-cbreak (&optional (stream *query-io*)) 
    (with-alien ((old (struct termios)) 
       (new (struct termios))) 
    (let ((e0 (unix-tcgetattr 0 old)) 
      (e1 (unix-tcgetattr 0 new)) 
      (bits (logior tty-icanon tty-echo tty-echoe 
         tty-echok tty-echonl))) 
     (declare (ignorable e0 e1)) ;[probably should test for error here] 
     (unwind-protect 
      (progn 
      (setf (slot new 'c-lflag) (logandc2 (slot old 'c-lflag) bits)) 
      (setf (deref (slot new 'c-cc) vmin) 1) 
      (setf (deref (slot new 'c-cc) vtime) 0) 
      (unix-tcsetattr 0 tcsadrain new) 
      (read-char stream)) 
     (unix-tcsetattr 0 tcsadrain old))))) 

SBCL शायद इस क्षेत्र में CMUCL से काफी अलग हो गयी है, लेकिन: बिना किसी संकेत को टर्मिनल स्क्रीन को खिलवाड़ करने के लिएएसबीसीएल के साथ कुछ ऐसा करने योग्य होना चाहिए। एसबी-यूनिक्स या शायद एसबी-POSIX संकुल में देख कर शुरू करें ...

User vippstar's response जो सबसे पोर्टेबल समाधान

हो सकता है जब से तुम कुछ करना चाहता हूँ के लिए एक लिंक प्रदान की है कि माइक्रोकंट्रोलर (लेकिन बेनिफिट अधिक उन्नत यूआई है) के लिए पोर्टेबल नहीं हो सकता है, गैर-मानक लाइब्रेरी, जैसे कि CL-ncurses का उपयोग करें।

+2

उत्कृष्ट, बस जब मैंने सवाल देखा तो मैं क्या सोच रहा था। अब मुझे जवाब लिखना नहीं है। – Vatine

0

मुझे cl-charms मिला, जो कि छोड़े गए सीएल-शापों का कांटा प्रतीत होता है। हालांकि, शामिल उदाहरण प्रोग्राम charms-paint छोटे रंग के अनुप्रयोग को चलाने के लिए 100% CPU का उपयोग करता है। समस्या यह प्रतीत होती है कि मुख्य लूप व्यस्त-इनपुट के लिए इंतजार कर रहा है।

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