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