Wer unter DOS angefangen hat, in C zu programmieren und dabei etwas erweiterte OberflŐchen gestaltet hat, wird schnell den "getch()"-Befehl aus der Header-Datei conio.h liebgewonnen haben. Wenn dann (aus irgendwelchen Grčnden) ein Umstieg auf Linux/Unix kommt und man so weiterarbeiten mÜchte, wie gewohnt, so wird man schnell merken, dass der Befehl nicht die gewohnte Wirkung entfaltet. Denn der Tastendruck kommt nur an, wenn abschliessend gedrčckt wird. Nun kann man entweder die Header-Datei "ncurses.h" mit der dahinterstehenden Bibliothek benutzen, sich in die Konsolenwelt einarbeiten oder aufgeben. Fčr alle, die dem letzteren nahe sind, habe ich die vorletzte Aufgabe erledigt, damit man nicht als Folge der ersten MÜglichkeit alle "printf()"-Aufrufe durch "wprintf()" ersetzen muss...
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>

int keypressed()
{
   fd_set input_fdset;
   int old_flags, old_flags2;
   struct termios term_attr;
   int c = 0;
   char c2[2];
   
   if (tcgetattr(STDIN_FILENO, &term_attr) != 0)
   {
      perror("getch:tcgetattr() failed!");
   }
   old_flags = term_attr.c_lflag;
   term_attr.c_lflag &= ~(ICANON | ECHOE);
   if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &term_attr) != 0)
   {
      perror("getch:tcsetattr() failed!");
   }

   if (tcgetattr(STDOUT_FILENO, &term_attr) != 0)
   {
      perror("getch:tcgetattr() failed!");
   }
   old_flags2 = term_attr.c_lflag;
   term_attr.c_lflag = 0;
   if (tcsetattr(STDOUT_FILENO, TCSAFLUSH, &term_attr) != 0)
   {
      perror("getch:tcsetattr() failed!");
   }
   
   FD_ZERO(&input_fdset);
   FD_SET(STDIN_FILENO, &input_fdset);
   if (select(STDIN_FILENO + 1, &input_fdset, NULL, NULL, NULL) == -1)
   {
      perror("getch:select() failed!");
   }
   if (FD_ISSET(STDIN_FILENO, &input_fdset))
   {
      c = 1;
   }
   
   term_attr.c_lflag = old_flags;
   if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &term_attr) != 0)
   {
      perror("getch:tcsetattr() failed!");
   }

   term_attr.c_lflag = old_flags2;
   if (tcsetattr(STDOUT_FILENO, TCSAFLUSH, &term_attr) != 0)
   {
      perror("getch:tcsetattr() failed!");
   }

   return(c);
}

char getch()  
{
   fd_set input_fdset;
   int old_flags, old_flags2;
   struct termios term_attr;
   char c = 0;
   
   if (tcgetattr(STDIN_FILENO, &term_attr) != 0)
   {
      perror("getch:tcgetattr() failed!");
   }
   old_flags = term_attr.c_lflag;
   term_attr.c_lflag &= ~(ICANON | ECHOE);
   if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &term_attr) != 0)
   {
      perror("getch:tcsetattr() failed!");
   }
   
   if (tcgetattr(STDOUT_FILENO, &term_attr) != 0)
   {
      perror("getch:tcgetattr() failed!");
   }
   old_flags2 = term_attr.c_lflag;
   term_attr.c_lflag = 0 ;
   if (tcsetattr(STDOUT_FILENO, TCSAFLUSH, &term_attr) != 0)
   {
      perror("getch:tcsetattr() failed!");
   }
      
   
   while (1)
   {
      FD_ZERO(&input_fdset);
      FD_SET(STDIN_FILENO, &input_fdset);
      if (select(STDIN_FILENO + 1, &input_fdset, NULL, NULL, NULL) == -1)
      {
         perror("getch:select() failed!");
      }
      if (FD_ISSET(STDIN_FILENO, &input_fdset))
      {
         if (read(STDIN_FILENO, &c, 1) == -1)
         {
            perror("getch:read() failed!");
         }
         else
         {
            break;
         }
      }
   }
   term_attr.c_lflag = old_flags;
   if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &term_attr) != 0)
   {
      perror("getch:tcsetattr() failed!");
   }
   term_attr.c_lflag = old_flags2;
   if (tcsetattr(STDOUT_FILENO, TCSAFLUSH, &term_attr) != 0)
   {
      perror("getch:tcsetattr() failed!");
   }

   return(c);
}

char getche()
{
   char c;
   c = getch();
   write(STDOUT_FILENO, &c, 1);
   return(c);
}
Die Nutzung ist entsprechend simpel:
int main(int argc, char * argv[])
{
 char c=0;
 c = getch();
 printf("Es wurde ein Zeichen gedrueckt. Empfangen: %i (dez) -- \"%c\".\n",c,c);
 if (c==0)
 {
   c = getch();
   printf("Es war ein Sonderzeichen! Naechstes Zeichen: %i (dez) -- \"%c\".\n", c,c);
 }
}

Stichworte:


Impressum