ncurses 和 stdin 阻塞

发布于 2024-08-10 14:30:11 字数 406 浏览 9 评论 0原文

我在 select() 集中有 stdin,并且每当用户键入并按 Enter 时,我想从 stdin 中获取字符串

但是 select 在按下 Enter 之前(在极少数情况下,在键入任何内容之前)会触发 stdin 准备读取。这会将我的程序挂在 getstr() 上,直到我按 Enter

我尝试设置 nocbreak() ,它真的很完美,除了屏幕上没有任何回显,所以我看不到我正在输入的内容。设置 echo() 不会改变这一点。

我也尝试过使用timeout(0),但结果更疯狂并且不起作用。

I have stdin in a select() set and I want to take a string from stdin whenever the user types it and hits 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.

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.

I also tried using timeout(0), but the results of that was even crazier and didn't work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

脸赞 2024-08-17 14:30:11

您需要做的是使用 getch() 函数检查字符是否可用。如果您在无延迟模式下使用它,该方法将不会阻塞。然后,您需要吃掉这些字符,直到遇到“\n”,然后将每个字符附加到结果字符串中。

另外,我使用的方法是使用 GNU readline 库。它支持非阻塞行为,但有关该部分的文档不是那么优秀。

这里包含一个您可以使用的小示例。它有一个选择循环,并使用 GNU readline 库:

#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

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.

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.

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;
}

Compile with:

gcc -Wall rl.c -lreadline
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文