简体   繁体   English

ncurses 库在按下的键上打印奇怪的字符

[英]ncurses library prints weird characters on key pressed

I have a thread that catches a key pressed through getch and if the key pressed is arrowUp or arrowDown then it scrolls my terminal using ncurses functions (incrementing an integer variable used to show elements from a linked list).我有一个线程可以捕获通过getch按下的键,如果按下的键是 arrowUp 或 arrowDown,那么它会使用 ncurses 函数滚动我的终端(递增 integer 变量,用于显示链表中的元素)。 This works fine most of the times but sometimes (usually when i hold an arrow pressed) ncurses prints on terminal weird and unexpected characters like 9;32H (it seems like an uncatched input).这在大多数情况下都可以正常工作,但有时(通常是当我按住箭头时)ncurses 在终端上打印奇怪和意外的字符,如9;32H (这似乎是一个未捕获的输入)。 Does anyone know how i can solve this?有谁知道我该如何解决这个问题?

问题截图

Here an MCVE这是一个 MCVE

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

#define MAX(a,b) ((a) > (b) ? (a) : (b))

void * listener(void* p){
    int* shift = (int*) p;
    int ch;
    while (1)
    {
        ch = getch();
        if(ch == KEY_UP){
            *shift = MAX(0, *shift - 1);
        }
        else if(ch == KEY_DOWN){
            *shift = *shift + 1;
        }
    }
}
 
int main(){
    char* c = malloc(100);

    for(int i = 0; i < 100; i++){
        c[i] = 'A' + (random() % 26);
    }

    int shift = 0;

    pthread_t th;

    initscr();
    raw();
    noecho();
    keypad(stdscr, TRUE);
    start_color();
    curs_set(0);

    pthread_create(&th, NULL, listener, (void*) &shift);

    while(1){
        for(int j = shift; j < shift+stdscr->_maxy; ++j){
            move(j-shift,0);
            clrtoeol();
            mvaddch(j-shift, 0, c[j]);
            refresh();
        }
    }

    endwin();   
    free(c);
    return 0;
}

This snippet shows my issue if you hold arrow down如果您按住箭头,此代码段会显示我的问题

EDIT: The issue seems to be related to getch() from different thread that modifies global variables of ncurses library.编辑:这个问题似乎与来自不同线程的getch()有关,该线程修改了 ncurses 库的全局变量。 Does anyone know a thread-safe way to get a char input?有谁知道获取 char 输入的线程安全方法?

You can solve your issue using getchar instead of getch since it seems not to be thread safe.您可以使用 getchar 而不是 getch 来解决您的问题,因为它似乎不是线程安全的。 You found out that getch modifies ncurses global variable and calls refresh() at the end, so if another thread is changing ncurses stuff (eg cursor position) your program may have an unexpected behavior (in your case printing escape characters representing set cursor position)您发现 getch 修改 ncurses 全局变量并在最后调用 refresh() ,因此如果另一个线程正在更改 ncurses 内容(例如光标位置),您的程序可能会出现意外行为(在您的情况下打印代表设置光标位置的转义字符)

I actually solved my issue using getchar instead of getch since it seems not to be thread safe.我实际上使用getchar而不是getch解决了我的问题,因为它似乎不是线程安全的。 I found out that getch modifies ncurses global variable and calls refresh() at the end, so if another thread is changing ncurses stuff (eg cursor position) your program may have an unexpected behavior (in my case printing escape characters representing set cursor position)我发现getch修改了 ncurses 全局变量并在最后调用refresh() ,因此如果另一个线程正在更改 ncurses 内容(例如光标位置),您的程序可能会出现意外行为(在我的情况下打印代表设置光标位置的转义字符)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM