如何在C中写入输入部分?
How to write to input part in C?
我正在尝试用 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
。
问题是我无法理解 ioctl
和 tty
函数的文档,而且我找不到关于这些函数的详细解释教程和示例,我找不到我正在尝试用它们做什么的文档。
有人可以用一种可以理解的方式向我解释这些功能吗?我应该如何将它们应用于我正在尝试做的事情(我正在寻找 Linux-MacOs 兼容方式)
感谢您的帮助。
您的要求很重要,需要大量的工作。基本上,您需要做的是使用 tcsetattr
将终端置于非规范模式,在该模式下终端的输入行缓冲被禁用,每次击键都会立即返回,而不是等待换行。然后您必须自己处理每个击键,包括 backspace/delete 和 up/down 箭头。由于您想对行编辑执行的操作,您可能还必须禁用回显并自己执行回显。
您需要自己维护当前行缓冲区,您还需要一个数据结构来存储所有较旧的输入行(历史记录),当向上箭头被点击时,您将需要擦除当前为输入缓冲的内容,并将其从屏幕上擦除,然后将历史记录复制到当前缓冲区并将其回显到终端。
另一个复杂的问题是向上箭头和向下箭头之类的键不是 ascii 的一部分,因此不会被读取为单个字节 -- 相反它们将是多字节转义序列(可能以 ESC 开头('\x1b'
) 个字符)。您可以使用 tgetstr
查询终端数据库以弄清楚它们是什么,或者只是硬编码您的 shell 以使用 ANSI sequences 这些天几乎所有终端都在使用。
我正在尝试用 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
。
问题是我无法理解 ioctl
和 tty
函数的文档,而且我找不到关于这些函数的详细解释教程和示例,我找不到我正在尝试用它们做什么的文档。
有人可以用一种可以理解的方式向我解释这些功能吗?我应该如何将它们应用于我正在尝试做的事情(我正在寻找 Linux-MacOs 兼容方式) 感谢您的帮助。
您的要求很重要,需要大量的工作。基本上,您需要做的是使用 tcsetattr
将终端置于非规范模式,在该模式下终端的输入行缓冲被禁用,每次击键都会立即返回,而不是等待换行。然后您必须自己处理每个击键,包括 backspace/delete 和 up/down 箭头。由于您想对行编辑执行的操作,您可能还必须禁用回显并自己执行回显。
您需要自己维护当前行缓冲区,您还需要一个数据结构来存储所有较旧的输入行(历史记录),当向上箭头被点击时,您将需要擦除当前为输入缓冲的内容,并将其从屏幕上擦除,然后将历史记录复制到当前缓冲区并将其回显到终端。
另一个复杂的问题是向上箭头和向下箭头之类的键不是 ascii 的一部分,因此不会被读取为单个字节 -- 相反它们将是多字节转义序列(可能以 ESC 开头('\x1b'
) 个字符)。您可以使用 tgetstr
查询终端数据库以弄清楚它们是什么,或者只是硬编码您的 shell 以使用 ANSI sequences 这些天几乎所有终端都在使用。