So lesen Sie den Eingabepuffer des Terminals unmittelbar nach dem Drücken von

Ich möchte Pfeiltasten in meinem c-Programm lesen und sie (sofort im Terminal selbst) durch eine andere Zeichenfolge ersetzen. Ich versuche, die Bash-History-Funktionalität wie in Unix-Terminals zu implementieren. Ich habe diesen Code geschrieben.

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

Aber dies funktioniert nicht, da Terminals auf eine neue Zeile oder EOF warten, um den Eingabepuffer an stdin zu senden. Ich muss also die Eingabetaste drücken, um die Benutzereingaben zu analysieren.

Hier in diesemAntworte der erwähnte Benutzer verwendetsystem ("/bin/stty raw"); aber dies ersetzt alle Standard-Terminal-Verhaltensweisen (z. B. Rücktaste, Löschen usw.).

Also, gibt es eine Möglichkeit, den Eingangspuffer des Terminals direkt zu lesen / zu manipulieren und den Puffer selbst zu optimieren, wenn Pfeiltastendruck erkannt wird?

Umwelt - Ubuntu (Linux)

Update 1: Gibt es eine Methode zum Ändern des Signals / Interrupts (standardmäßig wird die Eingabetaste gedrückt), mit der das Terminal die gespeicherte Eingabe an den Puffer sendet? Dies kann mir auch dabei helfen, dasselbe Verhalten zu erzielen.

Final Code:

Ich habe die ASCII-Zeichen für bestimmte Tastendrücke herausgefunden, indem ich die Ausgabe von @ überprüft habstrace 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;
}

Antworten auf die Frage(4)

Ihre Antwort auf die Frage