LordNoxx
Anmeldungsdatum: 16. Juni 2007
Beiträge: 358
|
Hallo,
wir haben heute in Informatik einen sog. Automaten programmiert. Sprache ist C/C++ . Unser Dozent meinte dann, wir sollen die Eingaben der Tastatur mit der Funktion getch() machen. Dazu müssten wir dann die conio.h includen. Jo denkste. Hat beim ganzen Kurs funktioniert,da die den Microsoft Compiler verwenden.
Doch bei mir auf meiner Linuxkiste mit dem gcc geht das nicht. Wie ich inzwischen rausgefunden habe, ist getch() kein ANSI-C Standard. Gibt es eine Möglichkeit, dass auch wir Linuxer sowas wie getch() verwenden können? PS: Ich bin c/c++ Anfänger, und habe von daher keine Ahnung wie ich mir eine solche getch-Funktion selber bastel ☺
|
Yoschi
Anmeldungsdatum: 11. April 2009
Beiträge: 454
|
In Linux und POSIX Systemen algemein gibt es sowas wie die Funktion getch() nicht, da sie nicht zu ANSI Standard gehört. Ich habe auf dieser Seite folgende Nachimplementierung gefunden:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 | #include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>
// Nachimplementierung der getch()-Funktion aus DOS-conio.h
// für POSIX-Betriebsysteme
// Lizenz: Public domain
int getch () {
int ch;
struct termios old_t, tmp_t;
// alte Attribute holen
if (tcgetattr (STDIN_FILENO, &old_t)) {
// moeglicherweise kein Terminal
// moeglicherweise anderer Fehler
return -1;
}
// struktur kopieren
memcpy (&tmp_t, &old_t, sizeof (old_t));
// Zeilenmodus sowie Spezialzeichen deaktivieren,
// Bildschirmausgabe von eingegebenen Zeichen
// deaktivieren
tmp_t.c_lflag &= ~ICANON & ~ECHO;
// Neue Flags setzen
if (tcsetattr (STDIN_FILENO, TCSANOW, (const struct termios *)&tmp_t)) {
// moeglicherweise irgend ein Fehler
return -1;
}
// zeichen einlesen (darauf verlassen,
// STDIN_FILENO blockierend ist)
ch = getchar ();
// Alte Flags zuruecksetzen
// Rueckgabewert ignorieren, da das Terminal bei Fehler sowieso
// nicht korrekt reagieren wird, wir dagegen aber nichts tun
// koennen
tcsetattr (STDIN_FILENO, TCSANOW, (const struct termios *)&old_t);
// Zeichen zurueckgeben
return ch;
}
|
Diese Funktion macht also folgendes:
Den Zeilenmodus des Terminals deaktivieren. Den Echo-Modus (automatische Ausgabe von eingegebenen Zeichen) des Terminals deaktivieren Das Zeichen per getchar() einlesen Den Echo-Modus wieder aktivieren Den Zeilenmodus wieder aktivieren
ANSI Standard ist die Funktion getchar(), bei der du allerdings noch Enter drücken musst MfG Yoschi
|
Lunar
Anmeldungsdatum: 17. März 2006
Beiträge: 5792
|
Anstatt die ganze Struktur zu kopieren, reicht es, den Wert von .c_lflag zu sichern. Die Casts sind zudem nicht nötig.
|
LordNoxx
(Themenstarter)
Anmeldungsdatum: 16. Juni 2007
Beiträge: 358
|
Also erstmal danke für die schnelle Hilfe...Werde es so schnell wie möglich ausprobieren.
@lunar: Sorry, aber kannst du mir das etwas genauer erläutern?
|
Lunar
Anmeldungsdatum: 17. März 2006
Beiträge: 5792
|
So:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 | #include <termios.h>
#include <stdio.h>
#include <unistd.h>
int getch () {
int ch;
struct termios tc_attrib;
if (tcgetattr(STDIN_FILENO, &tc_attrib))
return -1;
tcflag_t lflag = tc_attrib.c_lflag;
tc_attrib.c_lflag &= ~ICANON & ~ECHO;
if (tcsetattr(STDIN_FILENO, TCSANOW, &tc_attrib))
return -1;
ch = getchar();
tc_attrib.c_lflag = lflag;
tcsetattr (STDIN_FILENO, TCSANOW, &tc_attrib);
return ch;
}
|
|
Blattlaus
Anmeldungsdatum: 29. März 2006
Beiträge: 1399
|
LordNoxx schrieb: ...conio.h...
Und wieder einmal werden arme Studenten von einem Professor gequält, der der Überzeugung ist Borland C wäre das einzig wahre (und das man nie mehr als ein return pro Funktion haben darf und das break der Teufel persönlich ist. Begründung: Kann man keine Stuktogram zu malen...). Bin ich froh das ich Programmieren 1 hinter mir habe.
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4563
Wohnort: Berlin
|
Wenn break der Teufel ist, dann kann man ja gar keine switch -Anweisungen verwenden!? Wo Du gerade Struktogramme erwähnst: Wie würde man da eigentlich Ausnahmebehandlung unterbringen? Ich weiss, C hat das von Haus aus nicht, aber dann dürften diese Lehrer ja nie eine der moderneren Sprachen anfassen. Ich benutze in C manchmal goto dafür, aber das ist ja auch superböse. ☺
|
Kinch
Anmeldungsdatum: 6. Oktober 2007
Beiträge: 1261
|
Haben Struktogramme überhaupt eine praktische Bedeutung? Imho werden die nur verwendet um Neulingen den Programmfluss zu erklären; zu einem Zeitpunkt also, wo Try-Catch-Ausnahmebehandlung eh noch keine Rolle spielen. Das man es nicht schafft plattformunabhängiges C beizubringen, finde ich übrigens ein kleines Armutszeugnis. Ich würde jedenfalls dringend mal mit dem Dozenten in Dialog treten.
|
Marc_BlackJack_Rintsch
Ehemalige
Anmeldungsdatum: 16. Juni 2006
Beiträge: 4563
Wohnort: Berlin
|
@Kinch: Naja, die praktische Bedeutung ist halt Neulingen den Programmfluss zu erklären. 😉 Sie sind IMHO einfach auf zu kleine Programmteile beschränkt, als das sie wesentlich Vorteil gegenüber echtem Quelltext bringen. Ab da, wo man die Übersicht verliert, braucht man eher so etwas wie UML, also eine Notation um Zusammenhänge in grösseren Systemen zu vereinfachen.
|
Blattlaus
Anmeldungsdatum: 29. März 2006
Beiträge: 1399
|
Marc 'BlackJack' Rintsch schrieb: Wenn break der Teufel ist, dann kann man ja gar keine switch -Anweisungen verwenden!?
Nein, nein. break ist eine Ausnahme. Da darf man das. Konsequent uns so 🙄 Und ja, der Prof. ist ein Idiot. das kann ich ihm aber schlecht sagen.
|
hackepeter
Anmeldungsdatum: 8. Januar 2006
Beiträge: 185
Wohnort: München
|
Hallo, in der ncurses Bibliothek gibt's ein getch(). Falls dieses das gleich tut wie die Windows-Variante, hätte man
damit sogar etwas halbwegs portables. Siehe auch "man getch" (und die libncurses5-dev sollte installiert sein). Gruß HP
|
Lunar
Anmeldungsdatum: 17. März 2006
Beiträge: 5792
|
Das verlangt meines Wissens einen initialisierten curses-Bildschirm. Das wiederum setzt eine ganze Anzahl anderer Terminal-Attribute, die es für eine einfache Eingabe ungeeignet machen. Letztendlich wird ein Ansatz mit curses für die Eingabe eines Zeichens wohl komplexer als die Verwendung der hier gezeigten Funktion. curses ist eben eher für TUIs gedacht.
|
hackepeter
Anmeldungsdatum: 8. Januar 2006
Beiträge: 185
Wohnort: München
|
Lunar schrieb: Das verlangt meines Wissens einen initialisierten curses-Bildschirm. Das wiederum setzt eine ganze Anzahl anderer Terminal-
Da hast du recht, habe gerade auch http://stackoverflow.com/questions/905060/non-blocking-getch-ncurses gefunden. Gruß HP
|
Tuxubuntu
Anmeldungsdatum: 27. Februar 2015
Beiträge: 28
|
Und, gibt es nun eine Art getch() für Linux ohne curses-Bildschirm?
|
Dakuan
Anmeldungsdatum: 2. November 2004
Beiträge: 6339
Wohnort: Hamburg
|
Du wirst nicht viel anderes finden als im zweiten und fünften Post bereits gezeigt wurde. Ich habe damit auch mal experimentiert, und wie man sieht auf die gleichen Funktionen zurückgegriffen.
|