Hi,
On Wed, 30 Oct 2002, Kroll, Volker wrote:
On 2002-10-30 06:41:11, Jens-Uwe Kielmann wrote:
alle mir bekannten Eingabemöglichkeiten (fget, getc, ...) lesen von stdin welche gepuffert ist.
D.h. erst nach dem Betätigen der Eingabetaste wird vom Puffer gelesen.
Ich möchte aber, das ein auf der Tastatur eingegebenes Zeichen sofort im Programm zur
Verfügung steht.
Wie stelle ich das am einfachsten an?
Geht das nicht mit read()
Nein. Terminals sind was anderes als Files. Auch setvbuf() hilft hier
nicht, da Terminals schon vom Treiber her linebuffered sind. Wenn man
also partout nicht (n)curses nehmen will so muss man schon selber ran, und
den Terminalmodus veraendern. Ich hab mal unten ein Beispiel geschrieben.
Die Kommentare sollten genug Erklaerung bieten, wieso wie was gemacht
wird. Dieses Programm funktioniert unter allen Unixen, die termios haben.
Ciao,
Micha.
--
#include
#include
#include
int main()
{
int c;
struct termios orig_t;
if (isatty (0)) {
struct termios t;
if (tcgetattr (0, &t) < 0)
perror ("tcgetattr");
tcgetattr (0, &orig_t);
/* Switch off canonical mode. I.e. no line buffer, no special editing
characters. */
t.c_lflag &= ~ICANON;
/* But we want to have signals (^C and such). */
t.c_lflag |= ISIG;
/* And we don't want to translate CR into NL on input. */
t.c_iflag &= ~ICRNL;
/* We might want to switch off echoing of input characters, if we emit
them anyway. */
t.c_lflag &= ~ECHO;
if (tcsetattr (0, TCSANOW, &t) < 0)
perror ("tcsetattr");
}
while ((c = getc(stdin)) != EOF) {
/* Due to switching to non-canonical mode ^D is not interpreted as
EOF. Therefore check this explicitely (but only if it's a terminal
of course). */
if (isatty (0) && c == 0x04)
break;
printf ("%c\n", c);
}
/* Don't forget to reset the terminal mode. Otherwise you won't see anything
in your shell after running this program. */
if (isatty (0))
tcsetattr (0, TCSANOW, &orig_t);
return 0;
}