C程序中的标准输出转义查询和标准输入冲突(无ncurses)



我正在写一个没有护士的小cli程序,我面临一个问题。我使用转义序列来查询光标位置,这在用户没有输入或输入频率低时正常工作,但是当用户输入频率高时,这会影响我的查询响应。

我使用read来处理用户输入:

read(0, &c, sizeof(c))

我使用printf/scanf来处理转义序列查询:

printf("33[6n");
scanf("33[%d;%dR", y, x);

为了解决这个问题,我尝试在每次读取后获得光标位置。当我一直按一个键(例如"z")时,我在printf和scanf之间收到一些z,因此scanf失败。我期望在查询期间阻塞或缓冲用户输入,但不是:(.

在查询之后,我可以在scanf和buffer输入之前搜索stdin流上的序列,但是相当重,并且不是100%确定。

是否有一个简单的解决方案来解决这个问题?(保证顺序,阻止用户在查询前输入等)

编辑于2014-07-01 21:21:

我创建了一个小样本来说明这个问题。标准键没有问题,但UP键或HOME键污染printf/scanf查询序列…

// Build gcc -o test main.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
char getch();
void get_cursor_pos(int* x, int* y);
void reset_terminal_mode();
struct termios g_termios;
int main(int arc, char** argv)
{
    char c;
    int x,y;
    struct termios new_termios; 
    printf("TEST STDOUT/STDIN QUERYn");
    // Setting raw terminal
    printf("Setting raw terminal mode...n");
    tcgetattr(0, &g_termios);
    memcpy(&new_termios, &g_termios, sizeof(struct termios));
    atexit(reset_terminal_mode);
    cfmakeraw(&new_termios);            
    new_termios.c_oflag |= OPOST|ONLCR;
    tcsetattr(0, TCSANOW, &new_termios);
    // Main loop
    printf("Starting main loop...n");
    printf("(Press [=] to abort)n");
    do{
        c=getch();
    printf("0x%02X",c); 
    get_cursor_pos(&x,&y);
    printf("<%dx%d> ",x,y);         
    }while(c!='=');
    // End loop
    printf("nEndn");
    return EXIT_SUCCESS;
}
char getch()
{
    char c;
    read(0, &c, sizeof(c));
    return c;
}
void get_cursor_pos(int* x, int* y)
{
    *x=0; 
    *y=0;
    printf("33[6n");
    scanf("33[%d;%dR", y, x);
}
void reset_terminal_mode()
{
    printf("Reset terminal mode...n");
    tcsetattr(0, TCSANOW, &g_termios);
}

你能给我解释一下什么是追加吗?

Thanks in advance

您不能使用写的getch()来捕获HomeArrow密钥,因为密钥代码是多字节代码。您必须修改getch()函数来处理单字节和多字节输入,以捕获使用多字节代码的键。参见 C/c++中的Unicode 以获得相当全面的解释和处理多字节输入的例程示例。

最新更新