2017-06-01 5 views
3

Ich habe ein C-Programm, das den Benutzer nach seinem Namen mit ein wenig Code fragt, der von stdin auf einer while-Schleife liest (bis Enter gedrückt wird). Ich bin dafür, dass der Benutzer nur ASCII-Werte von 32 bis 126Verhindern von ANSI-Escapezeichen bei der Tastatureingabe in C

Das Problem ist, eintreten kann, wenn ich meinen Pfeil (Cursor) Tasten oder so etwas wie PAGE_DOWN oder andere drücke ... ich die ANSI am Ende mit Escape-Sequenz wird auf das Terminal gedruckt ([A, [6 ~ usw.)].

Hier ist der Codeabschnitt.

char name[6]; 
char c; 
uint8_t i = 0; 
while ((c = getchar()) != '\n') { 
    if (c == 127 || c == 8) { // Checks if backspace or del is pressed 
     i--; 
     name[i] = ' '; 
    } else if (c >= 32 && c <= 126) { // Only legal key presses please! 
     name[i] = c; 
     i++; 
    } else { 

    } 

    if ((c >= 32 && c <= 126) || c == 127 || c == 8) { 
     printf_P(PSTR("%c"), c); 
    } 
} 
name[5] = '\0'; 
move_cursor(15, 18); 
printf_P(PSTR("%s"), name); 

ich sicher gewählt haben ASCII-Werte außerhalb des 32-126 Bereich zu ignorieren, so was ist die Ursache dafür? Irgendwelche Ideen? Prost!

+2

stellen Sie ein MCVE bereit _https: //stackoverflow.com/help/mcve_ – CIsForCookies

+0

@CIsForCookies Thanks! Ich habe das passende gekappt hinzugefügt, aber ich kodiere für ein Terminal, das auf einem seriellen COM-Port zuhört, so ist der Code für reguläres stdout ein bisschen unterschiedlich. –

+0

Wenn es sich um eine Zuweisung handelt, lassen Sie das Terminal des Benutzers in Ruhe. Wenn Sie bessere UX für ein Produktionsprogramm wünschen, verwenden Sie GNU readline oder eine ähnliche Bibliothek anstelle von stdio. –

Antwort

5

Dies funktioniert wie erwartet. Mit Terminal-Emulationen der VT100-Familie, ein Tastendruck, um Cursor-up zum Beispiel sendet die folgende Sequenz auf Ihre Bewerbung:

<ESC>[A 

Nun wird die ESC (0x1b) ist das, was gestrippt wird, da es aus Ihrem ist gültiger Bereich. Aber die anderen Charaktere sind vollkommen gültig.

Um diese auch zu entfernen, muss Ihr Programm Terminal-Escape-Codes erkennen; Eine einfache Regel besteht darin, alle Zeichen aus dem Escape in den nächsten Buchstaben zu löschen. Dies wird nicht alle terminalen Escape-Sequenzen erfassen, aber für die gebräuchlichsten wird es ausreichen.

Hier können Sie ein list of common terminal control escape sequences

+0

Ich werde es versuchen! Wenn Sie sagen: "Dies wird nicht alle terminalen Escape-Sequenzen erfassen", liegt das daran, dass einige unterschiedliche Längen haben? Zum Beispiel haben die meisten die Form "[X], aber Seite unten ist" [6 ~ "? –

+0

@TristanBatchler Unterschiedliche Längen sind kein Problem, da Sie alle bis zum nächsten Buchstaben abziehen (nicht Ziffern!), Aber wenn Buchstaben vor dem Ende der Sequenz stehen, wird es nicht genug abziehen.Aber Sie werden selten eine dieser – Ctx

+0

Fantastic! Ich habe gerade angefangen zu versuchen, was du vorgeschlagen hast und es sieht schon gut aus. Danke für die Antwort! –

0

Der entsandte Code enthält keine bestimmte Schlüsselinformationen.

Damit diese Funktionalität funktioniert, muss der Code den "Modus" der Kommunikation mit dem Terminal ändern.

Der normale 'Modus' ist 'gekocht', wo die Tastenanschläge an das Terminal gesendet werden und Tastenanschläge wie 'Rücktaste' vom Terminaltreiber gehandhabt werden.

Um die gewünschte Funktionalität zu aktivieren, muss der "Modus" "roh" sein und "Echo" muss ausgeschaltet sein.

Verwandte Themen