按键后如何立即读取终端的输入缓冲区

我想在我的C程序中读取箭头按键,并用其他字符串替换它们(立即在终端本身中)。我正在尝试在UNIX终端中实现bash历史记录功能。我写了这段代码。

int

main(int argc, char *argv[])

{

char c;

char str[1024];

int i = 0;

while((c = fgetc(stdin)) != '\n'){

if(((int)c) == 27){

c=fgetc(stdin);

c=fgetc(stdin);

if (c == 'A')

{

printf("%c[A%c[2K",27, 27);

printf("UP");

}

}

str[i++] = c;

}

printf("\n");

return 0;

}

但是,这不起作用,因为终端等待换行符或EOF将输入缓冲区发送到stdin。因此,我必须按Enter / Return键来分析用户输入。

用户在此回答中提到要使用,system("/bin/stty raw");但这将替换所有默认的终端行为(例如,退格键,删除等)。

因此,如果检测到箭头按键,有什么办法可以直接读取/操作终端输入缓冲区并调整缓冲区本身?

是否有一种方法可以改变信号/中断(默认是按Enter键),从而使终端将存储的输入发送到缓冲区?这也可以帮助我实现相同的行为。

我通过检查的输出发现了特定按键的ASCII字符 strace bash

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <fcntl.h>

#include <termios.h>

#define ESCAPE '\33'

#define BACKSPACE '\177'

#define DELETE '~'

int main(){

struct termios termios_p;

struct termios termios_save;

tcgetattr(0, &termios_p);

termios_save = termios_p;

termios_p.c_lflag &= ~(ICANON|ECHO);

tcsetattr(0,TCSANOW, &termios_p);

char buff;

while(read(0, &buff, 1) >= 0){

if(buff > 0){

if(buff == ESCAPE){

read(0, &buff, 1);

read(0, &buff, 1);

if(buff == 'A'){

write(2, "up", 2);

}else if(buff == 'B'){

write(2, "down", 4);

}else if(buff == 'C'){

write(2, "\33[C", 3);

}else if(buff == 'D'){

write(2, "\10", 2);

}

}else if(buff == BACKSPACE){

write(2, "\10\33[1P", 5);

}else if(buff == DELETE){

write(2, "\33[1P", 4);

}else{

write(2,&buff,1);

}

// write(2,&buff,1);

if(buff == 'q'){

break;

}

}

}

tcsetattr(0,TCSANOW, &termios_save);

return 0;

}

回答:

看来您正在寻找这样的东西。

该程序实际上等待用户输入。如果按下向上箭头键,程序将打印“按下箭头键”,然后退出。如果按下了其他任何按钮,它将等待用户完成键入的内容并打印出来,然后退出。

#include <termios.h>

#include <unistd.h>

#include <fcntl.h>

#include <stdio.h>

int main()

{

struct termios oldt, newt;

char ch, command[20];

int oldf;

tcgetattr(STDIN_FILENO, &oldt);

newt = oldt;

newt.c_lflag &= ~(ICANON | ECHO);

tcsetattr(STDIN_FILENO, TCSANOW, &newt);

oldf = fcntl(STDIN_FILENO, F_GETFL, 0);

fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

while(1)

{

ch = getchar();

if (ch == '\033')

{ printf("Arrow key\n"); ch=-1; break;}

else if(ch == -1) // by default the function returns -1, as it is non blocking

{

continue;

}

else

{

break;

}

}

tcsetattr(STDIN_FILENO, TCSANOW, &oldt);

fcntl(STDIN_FILENO, F_SETFL, oldf);

if(ch != EOF)

{

ungetc(ch,stdin);ith

putchar(ch);

scanf("%s",command);

printf("\n%s\n",command);

return 1;

}

return 0;

}

以上是 按键后如何立即读取终端的输入缓冲区 的全部内容, 来源链接: utcz.com/qa/414228.html

回到顶部