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.14 Stream positionieren – fseek, rewind und ftell  toptop

Zuerst die Syntax von fseek():

#include <stdio.h>
int fseek(FILE *datei, long offset, int origin);

Mit fseek() kann der Schreib-/Lesezeiger des Streams datei verschoben werden. Die Positionierung wird mit offset und origin angegeben. origin gibt den Bezugspunkt an, von wo ab der Schreib-/Lesezeiger verschoben werden soll. offset gibt an, wie weit von diesem Bezugspunkt aus der Dateizeiger verschoben wird. Für origin sind drei symbolische Konstanten in der Headerdatei <stdio.h> deklariert:


Tabelle 18.6   Bezugspunkt für die Positionierung

Symbol Wert Offset-Rechnung ab
SEEK_SET 0 Anfang der Datei
SEEK_CUR 1 Aktuelle Position
SEEK_END 2 Ende der Datei

Ein kleines Beispiel, welches die Funktion von fseek() demonstrieren soll:

/* fseek.c */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
   FILE *quelle, *fehler;
   int c;
   char datei[20];
   long pos = 0;
   printf("Welche Datei wollen Sie Öffnen : ");
   scanf("%s",datei);
   fflush(stdin);
   if( (quelle=fopen(datei,"a+")) == NULL) {
      if((fehler=fopen("fehler.log","a+")) != NULL) {
         fprintf(fehler,"Konnte %s nicht oeffnen\n",datei);
         fprintf(stderr,"Konnte %s nicht oeffnen\n",datei);
         return EXIT_FAILURE;
      }
      fprintf(stderr,"Konnte %s nicht oeffnen\n",datei);
      return EXIT_FAILURE;
   }
   /* Das Zeichen '*' soll das Ende unserer Eingabe markieren */
   printf("Eingabe machen und mit '*' beenden\n");
   while( (c=getc(stdin)) != '*')
      putc(c,quelle);
   /* Sie setzen den Zeiger quelle an den Anfang der Datei */
   fseek(quelle, 0L, SEEK_SET);
   /* Sie geben die ganze Datei auf dem Bildschirm aus */
   printf("\nAusgabe der kompletten Datei : \n");
   while( (c=getc(quelle)) != EOF)
      putc(c,stdout);
   /* Zur Demonstration gehen Sie von der aktuellen Position
    * 10 Zeichen zurück und geben die letzten 10 Zeichen aus */
   printf("\nDie letzten 10 Zeichen : ");
   fseek(quelle, –10L, SEEK_CUR);
   while( (c=getc(quelle)) != EOF)
      putc(c,stdout);
   /* Sie legen selbst fest, wie viel Zeichen wir vom Start aus
    * einrücken wollen. */
   printf("\nAnzahl der Stellen einrücken (vom Anfang): ");
   scanf("%ld",&pos);
   fflush(stdin);
   fseek(quelle, 0L, SEEK_SET);
   fseek(quelle, pos,SEEK_CUR);
   while( (c=getc(quelle)) != EOF)
      putc(c,stdout);
   return EXIT_SUCCESS;
}

Abbildung
Hier klicken, um das Bild zu Vergrößern

Abbildung 18.5   Verschieben des Schreib-/Lesezeigers mit der Funktion fseek()

Zuerst wird eine Datei geöffnet. Falls dies nicht gelingt, wird eine Datei mit dem Namen »fehler.log« beschrieben. Anschließend wird so lange eine Eingabe gemacht, bis das Zeichen '*' eingegeben wurde. Die Eingabe wird an das Ende der Datei gehängt oder es wird, falls nicht vorhanden, eine entsprechende Datei erzeugt ("a+"-Modus). Dann wird mit

fseek(quelle, 0L, SEEK_SET);

der Schreib-/Lesezeiger des Streams quelle an den Anfang der Datei gesetzt, da SEEK_SET als Anfang der Datei deklariert ist. Wenn stattdessen Folgendes verwendet würde

fseek(quelle, 10L, SEEK_SET);

wäre der Schreib-/Lesezeiger vom Anfang der Datei um zehn Bytes nach vorne verschoben, also dann zehn Zeichen vom Dateianfang entfernt. Anschließend wird die vollständige Datei auf dem Bildschirm ausgegeben. Jetzt befindet sich der Schreib-/Lesezeiger am Ende der Datei. Als Nächstes wird mit

fseek(quelle, –10L, SEEK_CUR);

der Schreib-/Lesezeiger um zehn Stellen von der aktuellen Position (SEEK_CUR) zurückgeschoben. Es ist also auch möglich, negative Werte für offset anzugeben. Dabei werden die zehn letzten Zeichen auf dem Bildschirm ausgegeben. Dann erfolgt eine Abfrage, um wie viele Stellen der Schreib-/Lesezeiger des Streams quelle vom Anfang der Datei verschoben werden soll. Dies wird gleich programmtechnisch umgesetzt mit:

fseek(quelle, pos,SEEK_CUR);

Benötigen Sie die aktuelle Position des Schreib-/Lesezeigers im Stream datei, können Sie diesen mit der Funktion ftell() ermitteln. Die Syntax:

long ftell(FILE *datei);

Falls dabei ein Fehler auftritt, liefert diese Funktion einen Wert kleiner als 0 zurück. Bei Erfolg gibt sie die aktuelle Position des Schreib-/Lesezeigers in Byte zurück.

Die Funktion ftell() können Sie ebenso einsetzen, um die Größe einer Datei in Byte zu ermitteln:

/* ftell.c */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
   FILE *quelle;
   char datei[20];
   printf("Welche Datei wollen Sie Öffnen : ");
   scanf("%s",datei);
   if( (quelle=fopen(datei, "r")) == NULL) {
      fprintf(stderr, "Konnte %s nicht oeffnen\n", datei);
      return EXIT_FAILURE;
   }
   /* Wir setzen den FILE-Zeiger ans Ende der Datei */
   fseek(quelle, 0L, SEEK_END);
   printf("Die Datei ist %ld Bytes gross!!\n", ftell(quelle));
   return EXIT_SUCCESS;
}

Nachdem mit fseek() der FILE-Zeiger an das Ende der Datei positioniert wurde, kann mit ftell() die Position und auch die Größe in Byte abgefragt werden. ftell() liefert als Rückgabewert den Datentyp long.

Es existiert auch eine andere Möglichkeit, den Stream wieder zurück zum Anfang der Datei zu setzen. Statt mit

fseek(quelle, 0L, SEEK_SET);

kann dies auch mit der folgenden Funktion realisiert werden:

rewind(quelle);

Beide Funktionen erfüllen denselben Zweck. Die Syntax von rewind() lautet:

#include <stdio.h>
void rewind(FILE *datei);
 << 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