You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CLI程序中正确退出循环并避免终端重复提示符

问题:CLI程序退出后出现重复终端提示符

我在CLI程序中为用户提供三个选项,希望菜单保持开启直到用户输入“e”退出。我的实现代码如下:

(format t "~%(E)xit program - (M)ore details - enter (C)ustom data~%")
(loop
  (setq what-to-do-next (read-char))
  (cond ((char-equal what-to-do-next #\m)
         (format t "more details~%"))
        ((char-equal what-to-do-next #\c)
         (format t "custom data~%"))
        ((char-equal what-to-do-next #\e)
         ()))
  (when (char-equal what-to-do-next #\e)
    (return nil)))

程序可以运行,但结束后出现了重复的终端提示符:

(E)xit program - (M)ore details - enter (C)ustom calendar
e
[user@host ~]$ 
[user@host ~]$ 

我尝试添加退出变量的方式仍未解决问题:

(format t "~%(E)xit program - (M)ore details - enter (C)ustom data~%")
(setq exit 0)
(loop
  (setq what-to-do-next (read-char))
  (cond ((char-equal what-to-do-next #\m)
         (format t "more details~%"))
        ((char-equal what-to-do-next #\c)
         (format t "custom data~%"))
        ((char-equal what-to-do-next #\e)
         (setq exit 1)))
  (when (= exit 1)
    (return nil)))

请问我遗漏了什么,该如何避免这种重复提示符的问题?

解决方案

问题根源是:当你输入e并按下回车时,read-char仅读取了e字符,输入缓冲区里还残留着换行符\n。程序退出后,shell读取到这个残留的换行符,会误以为用户又敲了一次回车,因此输出重复的提示符。

以下是两种可行的解决方式:

方式一:退出前读取残留的换行符

在检测到e时,额外读取一次缓冲区里的换行符:

(format t "~%(E)xit program - (M)ore details - enter (C)ustom data~%")
(loop
  (setq what-to-do-next (read-char))
  (cond ((char-equal what-to-do-next #\m)
         (format t "more details~%"))
        ((char-equal what-to-do-next #\c)
         (format t "custom data~%"))
        ((char-equal what-to-do-next #\e)
         (read-char)) ; 读取残留的换行符
        )
  (when (char-equal what-to-do-next #\e)
    (return nil)))

方式二:清空输入缓冲区所有残留字符

如果用户可能输入多个字符再回车,这种方式更稳妥,确保缓冲区完全清空:

(format t "~%(E)xit program - (M)ore details - enter (C)ustom data~%")
(loop
  (setq what-to-do-next (read-char))
  (cond ((char-equal what-to-do-next #\m)
         (format t "more details~%"))
        ((char-equal what-to-do-next #\c)
         (format t "custom data~%"))
        ((char-equal what-to-do-next #\e)
         (progn
           ;; 循环读取并丢弃所有剩余缓冲字符
           (loop while (listen) do (read-char))
           (return nil)))
        ;; 忽略无效字符和换行
        (t nil)))

处理后输入缓冲区无残留字符,shell就不会输出重复的提示符了。

内容的提问来源于stack exchange,提问作者dpo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 18:55:32