【问题标题】:How to write to input part in C?如何在 C 中写入输入部分?
【发布时间】:2021-06-17 18:20:23
【问题描述】:

我正在尝试用 C 语言为一个学校项目编写一个迷你 shell,我想做的是做一种命令历史记录(就像在 shell 中一样),当我按下 UP 键时,它会将先前的输入写入输入部分,DOWN则相反,等等...,您可以在按Enter之前对其进行编辑以将其发送到程序,如下所示(抱歉英语不好):[]代表用户光标

my_shell$ some input wrote by me
my_shell$ []
my_shell$ some other input
my_shell$ []
and now if I press UP
my_shell$ some other input[]
If I press UP again
my_shell$ some input wrote by me[]

我可以使用 termcaps 和其他一些函数 isatty, ttyname, ttyslot, ioctl, getenv, tcsetattr, tcgetattr, tgetent, tgetflag, tgetnum, tgetstr, tgoto, tputs

问题是我无法理解 ioctltty 函数的文档,我找不到关于这些函数的详细解释的示例教程,也找不到我的文档我想和他们一起做。

有人可以以一种可以理解的方式向我解释这些功能吗?以及我应该如何将它们应用于我正在尝试做的事情(我正在寻找一种 Linux-MacOs 兼容方式) 感谢您的帮助。

【问题讨论】:

    标签: c ioctl termcap


    【解决方案1】:

    您要问的问题很重要,需要大量的工作。基本上,您需要做的是使用tcsetattr 将终端置于非规范模式,其中终端的输入行缓冲被禁用,并且每次击键都将立即返回,而不是等待换行。然后,您必须自己处理每个按键,包括退格/删除和向上/向下箭头。由于您想要对行编辑进行什么操作,您可能还必须禁用回显并自己执行回显。

    您需要自己维护当前行缓冲区,并且您还需要一个数据结构来存储所有较旧的输入行(历史记录),当按下向上箭头时,您需要擦除当前为输入缓冲的内容,并将其从屏幕上擦除,然后将历史记录复制到当前缓冲区并将其回显到终端。

    另一个复杂的问题是像向上箭头和向下箭头这样的键不是 ascii 的一部分,因此不会被读取为单个字节——而是它们将是多字节转义序列(可能以 ESC 开头(@ 987654323@) 字符)。您可以使用tgetstr 来查询终端数据库以确定它们是什么,或者只是硬编码您的shell 以使用ANSI sequences,这是您现在看到的几乎所有终端都使用的。

    【讨论】:

    • 谢谢,说的很清楚,看来我还有事要做:)
    • 只是一个问题,当启用非规范模式时,这是否仅用于写入缓冲区,或者我也可以将 read() 也用于一个字符,例如不需要回车的功能回来?
    • 非规范模式仅用于输入(读取缓冲区),根本不影响写入。它所做的只是让您无需等待返回即可读取每个字符(一次一个,或一次多个)。您还可以设置一个字符间计时器(因此没有延迟的字符,例如功能键或箭头等单次击键的字符都聚集在一起)。
    猜你喜欢
    • 2014-12-27
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 2015-10-02
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 2017-04-22
    相关资源
    最近更新 更多