复制并粘贴到非规范模块中

时间:2019-02-18 13:05:49

标签: c linux terminal

我正在创建一个程序来实现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"

2 个答案:

答案 0 :(得分:0)

ICRNL标志常量适用于c_iflag,而不适用于c_lflag。您将其关闭在错误的位置。对我来说还不清楚为什么要完全关闭 ,但是如果要这样做,则需要修改正确的标志集。

ECHOEECHOLECHONLECHOPRTECHOKE本地模式标志仅在规范模式下相关,您将其关闭。禁用这些功能也无害,但确实会使您的代码难以阅读和遵循。

关于

  

当我要复制字符串并将其粘贴时,它仅显示复制的字符串的第一个字符

,我怀疑您被输入计时器和/或非规范模式的最小字符计数属性所咬伤。这些由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
  • 否则,返回读取的char,转换为类型EOF

答案 1 :(得分:0)

如果我通过以下方式完成您的计划

int main()
{
    int i = ft_getch();
    printf("%x\n", i);
}

我知道

$ ./a.out
4c4c4548

当我尝试粘贴HELLO WORLD时,这是我期望的。 (48是H的十六进制代码,E是45的十六进制代码,L是4C的十六进制代码;当我使用的是小端格式时,它看起来是相反的。)