gpt4 book ai didi

c - getch() 确实显示最近输入的字符并跳过输入的所有其他字符

转载 作者:太空宇宙 更新时间:2023-11-03 23:41:13 26 4
gpt4 key购买 nike

正在做类作业并且已经与 ncurses 斗争了一段时间(这对我来说是新的)。创建一个能够通过网络与同一程序的另一个实例进行通信的程序。该程序的一部分是交互式地从键盘获取字符并将它们发送到接收端。 (我们被建议使用单线程方法并在 ncurses 中使用 getch,使用来自 getch 的非阻塞输入)。

我遇到的问题是我的 getch 有我无法弄清楚的行为。在不同的变体中,它会显示我输入的所有其他字符,并且不会显示最近输入的字符,直到在它之后输入另一个字符。我已经使用 nodelay() 来获取实时输入,但是。

这是我的 ncurses 显示设置。 (注意:我使用了 noecho(),因为稍后我不想显示输入的每个字符)。

/* initialize ncurses */
setlocale(LC_ALL,"");
initscr();
cbreak();
noecho();
nodelay(stdscr, TRUE);
nonl();
intrflush(stdscr, FALSE);
keypad(stdscr, TRUE);
clear();

这是我编写的与 getch 一起使用并通过套接字发送/接收数据的代码。

while(1) {
rfdset = master;

if (select(maxfd + 1, &rfdset, NULL, NULL, NULL) < 0) {
perror("select");
exit(EXIT_FAILURE);
}

ch = getch();

if (ch != ERR) {
printw("%c",ch);
write(direct, &ch, 1); // direction to send data
}

for(i = 0; i <= maxfd; i++) {
if (FD_ISSET(i, &rfdset)) {
bzero(msgbuf, MSGSIZE);
idx = read(i, msgbuf, MSGSIZE);
if (i != STDIN)
printw("%s",msgbuf); // display received msg
}
}
}

当我运行它并在应用程序的任何一端输入数据时,我得到的结果如下:

Computer 1 keyboard input: testing123
Computer 1 screen display: tsig2

Computer 2 message recv'd: tsig2

正因为如此,我确信是 getch 引起了我的大部分问题,我一定是在我的实现中遗漏了某些东西或做错了什么。任何建议表示赞赏。

编辑 1:

我设法通过删除 for 循环并直接检查套接字的输入来解决所有其他字符问题。我很困惑为什么要修复它。现在我唯一剩下的问题是为什么在输入字符后才显示字符。这是我在 while 循环中修改后的代码:

while(1) {
rfdset = master;

if (select(maxfd + 1, &rfdset, NULL, NULL, NULL) < 0) {
perror("select");
exit(EXIT_FAILURE);
}

ch = getch();

if (ch != ERR) {
printw("%c",ch);
write(direct, &ch, 1);
}

/* check for incoming data from left socket */
if (!NOLEFT && FD_ISSET(lcsad, &rfdset)) {
bzero(leftmsg, MSGSIZE);
idx = read(lcsad, leftmsg, MSGSIZE);
leftmsg[idx] = 0;
printw("%s", leftmsg);
lm = 1;
}

/* check for incoming data from right socket */
if (!NORIGHT && FD_ISSET(rsd, &rfdset)) {
bzero(rghtmsg, MSGSIZE);
idx = read(rsd, rghtmsg, MSGSIZE);
rghtmsg[idx] = 0;
printw("%s", rghtmsg);
rm = 1;
}

/* check and send left message onward */
if (lm && !NORIGHT) {
write(direct, leftmsg, MSGSIZE);
}

/* check and send right message onward */
if (rm && !NOLEFT) {
write(direct, rghtmsg, MSGSIZE);
}
lm, rm = 0;
}

最佳答案

问题在于,因为您的 select 调用没有指定超时(最后一个参数是 NULL),它会阻塞直到有一些未决的I/O(例如您键入的下一个字符)。此时,程序继续执行 getch 调用,执行 refresh(回显 printw 调用中的字符)。

指定一个较短的超时时间,例如 10 毫秒,会改善一些事情,例如,

struct timeval myTimeout;
myTimeout.tv_sec = 0;
myTimeout.tv_usec = 10000;

并在对select的调用中传递myTimeout的地址...

关于c - getch() 确实显示最近输入的字符并跳过输入的所有其他字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45016086/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com