Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

 << zurück
C von A bis Z von Jürgen Wolf
Das umfassende Handbuch für Linux, Unix und Windows
– 2., aktualisierte und erweiterte Auflage 2006
Buch: C von A bis Z

C von A bis Z
1.116 S., mit CD, Referenzkarte, 39,90 Euro
Galileo Computing
ISBN 3-89842-643-2
gp Kapitel 18 Ein-/Ausgabe-Funktionen
  gp 18.1 Was ist eine Datei?
  gp 18.2 Formatierte und unformatierte Ein-/Ausgabe
  gp 18.3 Streams
  gp 18.4 Höhere Ein-/Ausgabe-Funktionen
  gp 18.5 Datei (Stream) öffnen – fopen
    gp 18.5.1 Modus für fopen()
    gp 18.5.2 Maximale Anzahl geöffneter Dateien – FOPEN_MAX
  gp 18.6 Zeichenweise Lesen und Schreiben – getchar und putchar
    gp 18.6.1 Ein etwas portableres getch()
  gp 18.7 Zeichenweise Lesen und Schreiben – putc/fputc und getc/fgetc
  gp 18.8 Datei (Stream) schließen – fclose
  gp 18.9 Formatiertes Einlesen/Ausgeben von Streams mit fprintf und fscanf
  gp 18.10 Standard-Streams in C
    gp 18.10.1 Standard-Streams umleiten
  gp 18.11 Fehlerbehandlung von Streams – feof, ferror und clearerr
  gp 18.12 Gelesenes Zeichen in die Eingabe zurück-schieben – ungetc
  gp 18.13 (Tastatur-)Puffer leeren – fflush
    gp 18.13.1 Pufferung
  gp 18.14 Stream positionieren – fseek, rewind und ftell
  gp 18.15 Stream positionieren – fsetpos, fgetpos
  gp 18.16 Zeilenweise Ein-/Ausgabe von Streams
    gp 18.16.1 Zeilenweise Lesen mit gets/fgets
    gp 18.16.2 Zeilenweise Schreiben mit puts/fputs
    gp 18.16.3 Zeilenweise Einlesen vom Stream mit getline() (nicht ANSI C)
    gp 18.16.4 Rezepte für zeilenweises Einlesen und Ausgeben
  gp 18.17 Blockweise Lesen und Schreiben – fread und fwrite
    gp 18.17.1 Blockweises Lesen – fread()
    gp 18.17.2 Blockweises Schreiben – fwrite()
    gp 18.17.3 Big-Endian und Little-Endian
  gp 18.18 Datei (Stream) erneut öffnen – freopen
  gp 18.19 Datei löschen oder umbenennen – remove und rename
    gp 18.19.1 remove()
    gp 18.19.2 rename()
  gp 18.20 Pufferung einstellen – setbuf und setvbuf
  gp 18.21 Temporäre Dateien erzeugen – tmpfile und tmpnam
    gp 18.21.1 mkstemp() – Sichere Alternative für Linux/UNIX (nicht ANSI C)
  gp 18.22 Fehlerausgabe mit strerror und perror
  gp 18.23 Formatiert in einem String schreiben und formatiert aus einem String lesen – sscanf und sprintf
  gp 18.24 Fortgeschrittenes Thema
  gp 18.25 Low-Level-Datei-I/O-Funktionen (nicht ANSI C)
  gp 18.26 Datei öffnen – open
  gp 18.27 Datei schließen – close
  gp 18.28 Datei erzeugen – creat
  gp 18.29 Schreiben und Lesen – write und read
  gp 18.30 File-Deskriptor positionieren – lseek
  gp 18.31 File-Deskriptor von einem Stream – fileno
  gp 18.32 Stream von File-Deskriptor – fdopen


Galileo Computing - Zum Seitenanfang

18.6 Zeichenweise Lesen und Schreiben – getchar und putchar  downtop

Um zeichenweise aus dem Stream stdin (Standardeingabe) zu lesen und zeichenweise auf stdout (Standardausgabe) zu schreiben, können folgende Funktionen verwendet werden:

#include <stdio.h>
// Lesen (zeichenweise) von stdin
int getchar();
// Schreiben (zeichenweise) auf stdout
int putchar(int c);

getchar() dient zum Einlesen einzelner Zeichen von der Standardeingabe, normalerweise ist dies die Tastatur. Ein wenig verwirrend dürfte der Rückgabewert der Funktion getchar() sein, da dieser vom Datentyp int ist. Das liegt daran, dass ein char vor der Verwendung eines Ausdrucks in ein int konvertiert wird.

Etwas genauer: Das Problem der Verwendung von int liegt in der Konstante EOF (End of File), welche das Ende einer Eingabe anzeigt. EOF ist eine define-Konstante, die in der Headerdatei <stdio.h> mit dem Wert –1 deklariert ist, damit diese nicht mit den normalen ASCII-Zeichen kollidiert. Früher, als noch 127 Zeichen verwendet wurden, war das kein Problem. Heute sind die Werte der Zeichen größer als 127, um zum Beispiel Umlaute wie ä, ö, ü und ß ausgeben zu können. Ist char dabei mit unsigned deklariert, könnten Zeichen zwischen 0 ... 255 Platz darin finden. Es ist dann aber kein Platz mehr für EOF (-1). Daher wurde einfach der Rückgabewert von getchar() als int deklariert, und damit können sowohl die 255 Zeichen als auch das EOF übermittelt werden – das Problem war gelöst.

Hierzu ein Listing:

/* echo_char.c */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
   int c;
   while( (c = getchar()) !='.')
      putchar(c);
   return EXIT_SUCCESS;
}

Wenn hierbei mehrere Zeichen eingegeben werden und (˘) gedrückt wird, wird der Text Zeichen für Zeichen auf dem Bildschirm ausgegeben. Dies geschieht so lange, bis ein einzelnes Zeichen dem eines Punktes entspricht. Dann ist die while-Bedingung unwahr. Sie können als Abbruchbedingung auch EOF angeben:

while((c = getchar()) != EOF);

Hiermit werden solange Zeichen eingelesen, bis die Tastenkombination (Strg) + (Z) (unter MS-Systemen) oder (Strg) + (D) (unter Linux) gedrückt wird, welche EOF nachbildet.


Hinweis für Programmierneulinge   Auch wenn es bei der Funktion getchar() den Anschein hat, dass hier mit ganzen Strings gearbeitet wird, ist dem nicht so. Diese Funktion liest Zeichen für Zeichen aus einem Puffer.

Dies geschieht aber erst, wenn die Taste ENTER gedrückt wird. Suchen Sie nach einer Funktion, die auf Betätigung einer bestimmten Taste wartet, könnte die Funktion getch() für Sie interessant sein. Für MS-DOS steht diese Funktion sofort zur Verfügung, z.B.: while( (c=getch()) != 'q');. Damit wird das Programm so lange angehalten, bis die Taste q gedrückt wird. Unter Linux müssen Sie dafür die Bibliothek <ncurses.h> oder <termios.h> verwenden. Der Nachteil von getch() ist, dass das Programm damit schlecht auf ein anderes System portiert werden kann.


Zur Funktion getchar() noch ein Listing:

/* count_char.c */
#include <stdio.h>
#include <stdlib.h>
int main (void) {
   int c,counter=0;
   printf("Bitte Eingabe machen:");
   /* Eingabe machen bis mit Return beendet wird */
   while((c=getchar()) != '\n') {
      /* Leerzeichen und Tabulatorzeichen nicht mitzählen */
      if( (c != ' ') && (c != '\t') )
         counter++;     /* counter erhöhen */
   }
   /* Gibt die Anzahl eingegeb. Zeichen von 0 bis counter-1 aus
    * mit counter-1 wird das Zeichen '\0' nicht mitgezählt */
   printf("Anzahl der Zeichen beträgt %d Zeichen\n", counter-1);
   return EXIT_SUCCESS;
}

Mit diesem Listing werden alle darstellbaren Zeichen gezählt, die Sie über die Tastatur eingeben. Leerzeichen und Tabulatoren werden jedoch nicht mitgezählt.


Galileo Computing - Zum Seitenanfang

18.6.1 Ein etwas portableres getch()  toptop

Diese Frage wurde mir bereits unzählige Male gestellt: Wie kann ich den Programmablauf anhalten, bis eine bestimmte Taste gedrückt wird? Dafür gibt es leider keinen standardisierten Weg. Aber um Sie jetzt nicht im Regen stehen zu lassen, folgt hierfür ein etwas portableres getch(), welches sowohl unter Linux/UNIX als auch unter MS-Windows funktioniert. Ihnen diese Funktion speziell unter Linux/UNIX näher zu erklären, würde eine Spur zu weit gehen. Falls es Sie dennoch interessiert, können Sie mehr darüber auf meiner Homepage unter http://www.pronix.de erfahren. Bei MS-Windows gibt es dabei nicht viel zu sagen, nur dass die Headerdatei <conio.h> mit eingebunden werden muss, da sich darin diese Funktion befindet. Hier der Quellcode:

/* portable_getch.c */
#include <stdio.h>
#include <stdlib.h>
/* ... übersetzt unter Linux/UNIX? */
#ifdef __unix__
#include <termios.h>
#include <unistd.h>
static struct termios new_io;
static struct termios old_io;
/* Funktion schaltet das Terminal in den cbreak-Modus:        */
/* Kontrollflag ECHO und ICANON auf 0 setzen                  */
/* Steuerzeichen: Leseoperation liefert 1 Byte VMIN=1 VTIME=1 */
int cbreak(int fd) {
   /*Sichern unseres Terminals*/
   if((tcgetattr(fd, &old_io)) == –1)
      return –1;
   new_io = old_io;
   /*Wir verändern jetzt die Flags für den cbreak-Modus*/
   new_io.c_lflag = new_io.c_lflag & ~(ECHO|ICANON);
   new_io.c_cc[VMIN] = 1;
   new_io.c_cc[VTIME]= 0;
   /*Jetzt setzen wir den cbreak-Modus*/
   if((tcsetattr(fd, TCSAFLUSH, &new_io)) == –1)
      return –1;
   return 1;
}
int getch(void) {
   int c;
   if(cbreak(STDIN_FILENO) == –1) {
      printf("Fehler bei der Funktion cbreak ... \n");
      exit(EXIT_FAILURE);
   }
   c = getchar();
   /*Alten Terminal-Modus wiederherstellen*/
   tcsetattr(STDIN_FILENO, TCSANOW, &old_io);
   return c;
}
/* ... oder wird das Programm unter MS-Windows übersetzt? */
#elif __WIN32__ || _MSC_VER || __MS_DOS__
  #include <conio.h>
#endif
int main(void) {
  int zeichen;
  printf("Bitte 'q' drücken, um das Programm zu beenden!\n");
   /* Wartet auf das Zeichen q */
  while(( zeichen=getch() ) != 'q');
  return EXIT_SUCCESS;
}
 << zurück
  
  Zum Katalog
Zum Katalog: C von A bis Z
C von A bis Z
bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Shell-Programmierung






 Shell-Programmierung


Zum Katalog: Linux-UNIX-Programmierung






 Linux-UNIX-Programmierung


Zum Katalog: C/C++






 C/C++


Zum Katalog: UML 2.0






 UML 2.0


Zum Katalog: Reguläre Ausdrücke






 Reguläre Ausdrücke


Zum Katalog: Linux






 Linux


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo





Copyright © Galileo Press 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de