
Adam
Ich kann mich nie erinnern, wie ich das mache, weil es so selten für mich vorkommt. Aber in C oder C++, was ist der beste Weg, um ein Zeichen von der Standardeingabe zu lesen, ohne auf einen Zeilenumbruch zu warten (drücken Sie die Eingabetaste).
Idealerweise würde es das eingegebene Zeichen auch nicht auf dem Bildschirm wiedergeben. Ich möchte nur Tastenanschläge erfassen, ohne den Konsolenbildschirm zu beeinflussen.

Johannes Schaub – litb
Das ist portabel in reinem C++ nicht möglich, da es zu sehr vom verwendeten Endgerät abhängt, mit dem man sich verbinden kann stdin
(sie sind normalerweise zeilengepuffert). Sie können dafür jedoch eine Bibliothek verwenden:
-
conio verfügbar mit Windows-Compilern. Verwenden Sie die _getch()
Funktion, um Ihnen ein Zeichen zu geben, ohne auf die Eingabetaste zu warten. Ich bin kein häufiger Windows-Entwickler, aber ich habe gesehen, dass meine Klassenkameraden einfach enthalten <conio.h>
und benutze es. Sehen conio.h
bei Wikipedia. Es listet auf getch()
die in Visual C++ als veraltet deklariert ist.
-
Flüche für Linux verfügbar. Kompatible Curses-Implementierungen sind auch für Windows verfügbar. Es hat auch eine getch()
Funktion. (Versuchen man getch
um seine Manpage anzuzeigen). Sehen Flüche bei Wikipedia.
Ich würde Ihnen empfehlen, Flüche zu verwenden, wenn Sie plattformübergreifende Kompatibilität anstreben. Ich bin mir jedoch sicher, dass es Funktionen gibt, mit denen Sie die Zeilenpufferung ausschalten können (ich glaube, das heißt “Raw-Modus” im Gegensatz zum “Cooked-Modus” – schauen Sie sich das an man stty
). Wenn ich mich nicht irre, würden Curses das auf tragbare Weise für Sie erledigen.
Unter Linux (und anderen Unix-ähnlichen Systemen) kann dies auf folgende Weise erfolgen:
#include <unistd.h>
#include <termios.h>
char getch() {
char buf = 0;
struct termios old = {0};
if (tcgetattr(0, &old) < 0)
perror("tcsetattr()");
old.c_lflag &= ~ICANON;
old.c_lflag &= ~ECHO;
old.c_cc[VMIN] = 1;
old.c_cc[VTIME] = 0;
if (tcsetattr(0, TCSANOW, &old) < 0)
perror("tcsetattr ICANON");
if (read(0, &buf, 1) < 0)
perror ("read()");
old.c_lflag |= ICANON;
old.c_lflag |= ECHO;
if (tcsetattr(0, TCSADRAIN, &old) < 0)
perror ("tcsetattr ~ICANON");
return (buf);
}
Grundsätzlich müssen Sie den kanonischen Modus (und den Echomodus zur Unterdrückung von Echos) ausschalten.

cwiii
Ich habe dies in einem anderen Forum gefunden, als ich nach der Lösung des gleichen Problems suchte. Ich habe es ein wenig von dem, was ich gefunden habe, modifiziert. Es funktioniert großartig. Ich verwende OS X. Wenn Sie also Microsoft ausführen, müssen Sie den richtigen system() -Befehl finden, um in den Raw- und den Cooked-Modus zu wechseln.
#include <iostream>
#include <stdio.h>
using namespace std;
int main() {
// Output prompt
cout << "Press any key to continue..." << endl;
// Set terminal to raw mode
system("stty raw");
// Wait for single character
char input = getchar();
// Echo input:
cout << "--" << input << "--";
// Reset terminal to normal "cooked" mode
system("stty cooked");
// And we're out of here
return 0;
}
CONIO.H
Die Funktionen, die Sie benötigen, sind:
int getch();
Prototype
int _getch(void);
Description
_getch obtains a character from stdin. Input is unbuffered, and this
routine will return as soon as a character is available without
waiting for a carriage return. The character is not echoed to stdout.
_getch bypasses the normal buffering done by getchar and getc. ungetc
cannot be used with _getch.
Synonym
Function: getch
int kbhit();
Description
Checks if a keyboard key has been pressed but not yet read.
Return Value
Returns a non-zero value if a key was pressed. Otherwise, returns 0.
libconio
http://sourceforge.net/projects/libconio
oder
Linux c++ Implementierung von conio.h
http://sourceforge.net/projects/linux-conioh

Hasen
Wenn Sie Windows verwenden, können Sie verwenden PeekConsoleInput um zu erkennen, ob es eine Eingabe gibt,
HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
DWORD events;
INPUT_RECORD buffer;
PeekConsoleInput( handle, &buffer, 1, &events );
Verwenden Sie dann ReadConsoleInput, um das Eingabezeichen zu “verbrauchen”.
PeekConsoleInput(handle, &buffer, 1, &events);
if(events > 0)
{
ReadConsoleInput(handle, &buffer, 1, &events);
return buffer.Event.KeyEvent.wVirtualKeyCode;
}
else return 0
Um ehrlich zu sein, stammt das aus einem alten Code, den ich habe, also müssen Sie ein bisschen damit herumspielen.
Das Coole ist jedoch, dass Eingaben ohne Aufforderung gelesen werden, sodass die Zeichen überhaupt nicht angezeigt werden.
#include <conio.h>
if (kbhit() != 0) {
cout << getch() << endl;
}
Dies nutzt kbhit()
um zu überprüfen, ob die Tastatur gedrückt und verwendet wird getch()
um das gedrückte Zeichen zu erhalten.

sinfod
Ich verwende kbhit(), um zu sehen, ob ein Zeichen vorhanden ist, und dann getchar(), um die Daten zu lesen. Unter Windows können Sie “conio.h” verwenden. Unter Linux müssen Sie Ihr eigenes kbhit() implementieren.
Siehe Code unten:
// kbhit
#include <stdio.h>
#include <sys/ioctl.h> // For FIONREAD
#include <termios.h>
#include <stdbool.h>
int kbhit(void) {
static bool initflag = false;
static const int STDIN = 0;
if (!initflag) {
// Use termios to turn off line buffering
struct termios term;
tcgetattr(STDIN, &term);
term.c_lflag &= ~ICANON;
tcsetattr(STDIN, TCSANOW, &term);
setbuf(stdin, NULL);
initflag = true;
}
int nbbytes;
ioctl(STDIN, FIONREAD, &nbbytes); // 0 is STDIN
return nbbytes;
}
// main
#include <unistd.h>
int main(int argc, char** argv) {
char c;
//setbuf(stdout, NULL); // Optional: No buffering.
//setbuf(stdin, NULL); // Optional: No buffering.
printf("Press key");
while (!kbhit()) {
printf(".");
fflush(stdout);
sleep(1);
}
c = getchar();
printf("\nChar received:%c\n", c);
printf("Done.\n");
return 0;
}
10017400cookie-checkErfassen Sie Zeichen aus der Standardeingabe, ohne auf das Drücken der Eingabetaste zu wartenyes
@adam – Können Sie klarstellen: Möchten Sie eine Funktion, die sofort zurückkehrt, wenn kein Zeichen verfügbar ist, oder eine, die immer auf einen einzelnen Tastendruck wartet?
– Roddy
8. Januar 2009 um 9:47 Uhr
@Roddy – Ich möchte eine Funktion, die immer auf einen einzelnen Tastendruck wartet.
– Adam
28. Mai 2009 um 4:52 Uhr