c - 使用管道或重定向时 Ncurses 闪烁

标签 c input ncurses getch

当使用“unix 管道”和“重定向”进行输入时,Ncurses 会闪烁。也就是说,如果我输入自己但在使用“|”时却没有,它会很好地绘制或“<”。

我认为这可能是由于 getch() 延迟模式(无延迟、半延迟和无限延迟)所致。所以我明确地尝试设置 nodelay(stdscr, FALSE); 但很明显,它没有解决问题。

这是最小的工作代码:

#include <ncurses.h>
#include <stdlib.h>
#include <string.h>

/* Default assumptions */
#define BUFSIZE         100
#define SELINDICATOR    ">>> "
#define MAXITEMS        LINES   /* Decides how many items are shown at a time. By default, it's (number of rows - 1) */

/* Declarations */
static void draw(char **data, short index, short selected);
static void handleInput(short *selected, short index);

int main(int argc, char *argv[]) {

    char buf[BUFSIZE], **data;
    short index = 0, selected = 1;
    size_t curSize = 0;

    /* Get the entries */
    while(fgets(buf, BUFSIZE, stdin)) {

        if(!(data = realloc(data, (curSize += sizeof(char *))))) {
            fprintf(stderr, "error reallocating memory!\n");
            exit(1);
        }

        if(!(data[index] = malloc(BUFSIZE))) {
            fprintf(stderr, "error reallocating memory!\n");
            exit(1);
        }

        strcpy(data[index], buf);
        index++;
    }

    /* Start nCurses */
    initscr();
    noecho();
    nodelay(stdscr, FALSE); // just tryin' it out if it works

    while(1) {

        draw(data, index, selected);
        handleInput(&selected, index);
    }

    /* Quit nCurses */
    endwin();

    /* Free allocated memories */
    for(short i = 0; i < index; i++)
        free(data[i]);
    free(data);

    return 0;
}

void
draw(char **data, short index, short selected) {

    static short posX = strlen(SELINDICATOR), posY; /* posY doesn't need to be static but it makes no difference and looks cleaner */

        /* Clear old garbage */
        clear();
        posY = 0;

        /* Draw line echoing inputs */
        mvaddch(posY, 0, '>');
        posY++;

        /* Draw the entries */
        for(short i = 0; posY < COLS && i < index; i++) {

            if(posY == selected) {
                mvprintw(posY, 0, SELINDICATOR);
            }

            mvprintw(posY, posX, "%s", data[i]);
            refresh();
            posY++;
        }

        /* Make the output visible */
        refresh();
}

void
handleInput(short *selected, short numOfEntries) {

    int input = getch();

    /* A whole bunch of other stuff........ */

    endwin();
    exit(0);
}

非常感谢您的努力!

最佳答案

Ncurses 是作为提供交互式 用户界面的工具而设计和构建的。在某种程度上,它从标准输入(而不是直接从终端)读取输入,基于 ncurses 的程序可以将其输入从文件或管道重定向,但不清楚为什么它很重要在这种情况下实际显示用户界面。如果这样做会导致不需要的视觉效果,那么最简单的缓解措施可能是在这种情况下禁用 UI。

在问题中提供的程序中,显示 UI 与读取和处理输入完全分开,并且读取输入仅最低限度地依赖于 ncurses。修改此类程序以使其能够在 UI 和无 UI 模式之间切换应该非常简单,我建议您这样做。为此,您可能会找到 isatty()用于确定标准输入(和/或标准输出)是否为终端的函数。

关于c - 使用管道或重定向时 Ncurses 闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57546782/

相关文章:

javascript - 使用 jQuery 更新输入值属性

java - 实时替换用户输入击键(Java)

c - 使用 NCurses 和 C 来显示系统信息的简单文本 GUI (TUI)

c++ - 无法使用 nixos 推导包含 <ncurses.h> header

c - 为什么 printf() 在 Windows 上打印这个神秘的额外文本?

c - printf() 与 scanf() 在同一行

c - 程序立即以退出代码 0 结束——但它不应该在没有输入的情况下到达那里

c++ - 有没有办法用 C++ 模拟 Windows 输入?

c - 为什么有些函数特别长? (学术研究所需的想法!)

c - Ncurses 库和从文件中读取