c - 在非规范模式中复制和粘贴
问题描述
我正在创建一个程序来实现一个 linux shell
我已将终端模式更改为非规范
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"
解决方案
ICRNL
标志常数适用于,c_iflag
而不适用于。c_lflag
您在错误的地方将其关闭。我不清楚你为什么要关闭它,但如果你想这样做,那么你需要修改正确的标志集。
, ECHOE
, ECHOL
, ECHONL
,ECHOPRT
和ECHOKE
local-mode 标志仅与您要关闭的规范模式相关。关闭这些也不应该是有害的,但它确实使你的代码比它需要的更难阅读和遵循。
关于
当我想复制一个字符串并粘贴它时,它只显示复制字符串的第一个字符
,我怀疑您被输入计时器和/或非规范模式的最小字符数属性所困扰。这些由您的 termios 结构中的“特殊字符”数组的c_cc[VTIME]
和元素控制。c_cc[VMIN]
如果您正在配置一个支持交互式输入的终端,或者在输入中可能存在无限长度暂停,那么您需要关闭计时器并通过设置确保读取正确阻塞
new_opts.c_cc[VTIME] = 0;
new_opts.c_cc[VMIN] = 1;
. 但是,我不确定这是否足以满足您的目的,部分原因是我无法判断您阅读输入的方式是否会导致问题。
更新:
既然您现在已经公开了您的输入功能,我可以说如果它应该提供一个等效于getc()
. 您一次读取四个字节而不是一个字节,并且您没有正确处理 EOF 或错误。此外,多字节读取引入了您无法检测或处理的短读取的可能性。
如果您尝试一次读取一个字符,请执行此操作。的返回值getc()
不是因为尝试从流中读取 s 是合适的,而是提供了无效s 的结果值——特别是.int
char
int
char
EOF
我拒绝为您重写您的代码,但要模拟getc()
,它需要这样做:
- 一次读
char
一个 - 检查的返回值
read
。如果它不是 1(对于单字符读取),则返回EOF
- 否则,返回读取的字符,转换为 type
unsigned char
。
推荐阅读
- reactjs - 在 React 中使用 TypeScript 时“this.state”从何而来
- python - Discord Bot 不响应命令
- encryption - 当密钥具有特定长度(以位为单位)时,这意味着什么?
- python - 如何(有效地)找到足够有效数字所需的最小序列长度?
- mysql - 仅使用 xamarin Andriod 连接到 mySQL 数据库时出现问题,但在 iOS 和 UWP 中有效
- swiftui - SwiftUI 不发布模型实例
- python - 修改 YAML 内容
- css - 在锚标记内调整图像大小
- git - 如何使用 gerrit 审查复杂的樱桃精选
- javascript - React SetState 覆盖整个对象而不是合并