ncurses和stdin阻止 [英] ncurses and stdin blocking

查看:97
本文介绍了ncurses和stdin阻止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆