ncurses和stdin阻止 [英] ncurses and stdin blocking
问题描述
我在select()
集中有 stdin ,我想从用户输入 stdin 的任何字符串并按 Enter
I have stdin in a select()
set and I want to take a string from stdin whenever the user types it and hits Enter.
但是在按下 Enter 之前(在极少数情况下,根本没有输入任何内容之前),select会触发 stdin 准备读取.这会将我的程序挂在getstr()
上,直到我按下 Enter .
But select is triggering stdin as ready to read before Enter is hit, and, in rare cases, before anything is typed at all. This hangs my program on getstr()
until I hit Enter.
我尝试设置了nocbreak()
,它非常完美,除了屏幕上没有任何回声,因此我看不到我在输入什么.设置echo()
不会改变它.
I tried setting nocbreak()
and it's perfect really except that nothing gets echoed to the screen so I can't see what I'm typing. And setting echo()
doesn't change that.
我也尝试使用timeout(0)
,但是这样做的结果甚至更疯狂,而且行不通.
I also tried using timeout(0)
, but the results of that was even crazier and didn't work.
推荐答案
您需要做的是通过getch()函数检查字符是否可用.如果在无延迟模式下使用该方法,则该方法将不会阻塞.然后,您需要吃掉字符,直到遇到'\ n',然后将每个字符附加到结果字符串中.
What you need to do is tho check if a character is available with the getch() function. If you use it in no-delay mode the method will not block. Then you need to eat up the characters until you encounter a '\n', appending each char to the resulting string as you go.
或者,我使用的方法是使用GNU readline库.它支持非阻塞行为,但是有关该部分的文档不是那么好.
Alternatively - and the method I use - is to use the GNU readline library. It has support for non-blocking behavior, but documentation about that section is not so excellent.
此处包括一个可供您使用的小示例.它具有一个选择循环,并使用GNU readline库:
Included here is a small example that you can use. It has a select loop, and uses the GNU readline library:
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <stdlib.h>
#include <stdbool.h>
int quit = false;
void rl_cb(char* line)
{
if (NULL==line) {
quit = true;
return;
}
if(strlen(line) > 0) add_history(line);
printf("You typed:\n%s\n", line);
free(line);
}
int main()
{
struct timeval to;
const char *prompt = "# ";
rl_callback_handler_install(prompt, (rl_vcpfunc_t*) &rl_cb);
to.tv_sec = 0;
to.tv_usec = 10000;
while(1){
if (quit) break;
select(1, NULL, NULL, NULL, &to);
rl_callback_read_char();
};
rl_callback_handler_remove();
return 0;
}
编译为:
gcc -Wall rl.c -lreadline
这篇关于ncurses和stdin阻止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!