我正在创建一个程序来实现linux shell
我已将终端mod更改为非规范
void ft_getch_prepare(void)
{
int ret;
struct termios new_opts;
ret = tcgetattr(STDIN_FILENO, &new_opts);
new_opts.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK
| ECHONL | ECHOPRT | ECHOKE | ICRNL);
new_opts.c_cc[VMIN] = 1;
new_opts.c_cc[VTIME] = 1;
ret += tcsetattr(STDIN_FILENO, TCSANOW, &new_opts);
}
int ft_getch(void)
{
int c;
c = 0;
ft_getch_prepare();
read(0, &c, 4);
return (c);
}
但是当我要复制字符串并将其粘贴时,它仅显示复制的字符串的第一个字符
例如,我想将此字符串"HELLO WORLD"
粘贴到我的终端中,但是
它仅显示第一个字符"H"
答案 0 :(得分:0)
ICRNL
标志常量适用于c_iflag
,而不适用于c_lflag
。您将其关闭在错误的位置。对我来说还不清楚为什么要完全关闭 ,但是如果要这样做,则需要修改正确的标志集。
ECHOE
,ECHOL
,ECHONL
,ECHOPRT
和ECHOKE
本地模式标志仅在规范模式下相关,您将其关闭。禁用这些功能也无害,但确实会使您的代码难以阅读和遵循。
关于
当我要复制字符串并将其粘贴时,它仅显示复制的字符串的第一个字符
,我怀疑您被输入计时器和/或非规范模式的最小字符计数属性所咬伤。这些由termios结构中“特殊字符”数组的c_cc[VTIME]
和c_cc[VMIN]
元素控制。如果您要配置支持交互式输入的终端,或者输入可能会无限制地暂停输入,那么您需要关闭计时器并通过设置来确保读取正确阻塞
new_opts.c_cc[VTIME] = 0;
new_opts.c_cc[VMIN] = 1;
。我不确定这是否足以满足您的目的,部分原因是我无法判断您阅读输入内容的方式是否会导致问题。
更新:
既然您已经公开了输入函数,那么可以说,如果它应该提供等效于getc()
的接口,则确实存在很大的问题。您一次读取四个字节,而不是一个字节,并且没有正确处理EOF或错误。此外,多字节读取会引入 short 读取的可能性,而您不会检测或处理。
如果您想一次读取一个字符,请这样做。 getc()
的返回值是int
而不是char
,不是因为尝试从流中读取int
而是提供无效的结果值{ {1}}个,具体是char
。
我拒绝为您重写代码,但是要模拟EOF
,它需要这样做:
getc()
char
的返回值。如果它不是1(读取一个字符),则返回read
EOF
。答案 1 :(得分:0)
如果我通过以下方式完成您的计划
int main()
{
int i = ft_getch();
printf("%x\n", i);
}
我知道
$ ./a.out
4c4c4548
当我尝试粘贴HELLO WORLD时,这是我期望的。 (48是H的十六进制代码,E是45的十六进制代码,L是4C的十六进制代码;当我使用的是小端格式时,它看起来是相反的。)