Dateiverarbeitung Pearson Education, Inc. All rights reserved

1 9 Dateiverarbeitung  2006 Pearson Education, Inc. All rights reserved. 2 9.1 9.2 9.3 9.4 9.5 9.6 9.7 9.8 9.9 9.10 9.11 Einführung Die Datenhie...
Author: Adolph Albert
0 downloads 0 Views 344KB Size
1

9 Dateiverarbeitung  2006 Pearson Education, Inc. All rights reserved.

2

9.1 9.2 9.3 9.4 9.5 9.6 9.7 9.8 9.9 9.10 9.11

Einführung Die Datenhierarchie Daten und Ströme Erzeugung einer sequenziellen Datei Daten von einer sequenziellen Datei lesen Eine sequenzielle Datei aktualisieren Dateien mit wahlfreiem Zugriff Erzeugung einer Datei mit wahlfreiem Zugriff Daten wahlfrei in eine Datei mit wahlfreiem Zugriff schreiben Sequenzielles Lesen aus einer Datei mit wahlfreiem Zugriff Fallstudie: Verarbeitung von Transaktionen

 2006 Pearson Education, Inc. All rights reserved.

3

9.1 Einführung • Dateien – Werden verwendet, um Daten dauerhaft (‘persistent’) zu machen • Permanente Speicherung von großen Datenmengen

– Speicherung auf sekundären Speichereinheiten • Magnetplatten • Halbleiterspeicher (Flash-Speicher) • Optische Speichermedien • Magnetbänder

 2006 Pearson Education, Inc. All rights reserved.

4

9.2 Die Datenhierarchie • Bit – Darstellung von einem von zwei Zuständen, 0 oder 1 – Kleinste unterstützte Dateneinheit • Direkt in Hardwareschaltungen abgebildet

• Zeichen – Ziffern, Buchstaben und spezielle Symbole • Aus Bits zusammengesetzt

– Zeichensatz: Menge aller Zeichen, die auf einer bestimmten Plattform verwendet werden – chars werden in Bytes gespeichert (8 Bits) – wchar_ts werden in mindestens zwei Bytes gespeichert  2006 Pearson Education, Inc. All rights reserved.

5

9.2 Die Datenhierarchie • Feld – Aus Zeichen zusammengesetzt – Hat eine bestimmte Bedeutung – Beispiel • Groß- und Kleinbuchstaben können einen Namen darstellen

• Datensatz (Record) – Aus mehreren Feldern zusammengesetzt – Wird in C als Struktur dargestellt – Beispiel • Datensatz für einen Angestellten könnte Personalnummer, Name, Adresse usw. enthalten

– Ein Datensatz-Schlüssel ist ein Feld, das für alle Datensätze eindeutig ist.  2006 Pearson Education, Inc. All rights reserved.

6

9.2 Die Datenhierarchie • Datei – Aus einer Gruppe zusammengehöriger Datensätze zusammengesetzt – Beispiel: • Gehaltsdatei, die einen Datensatz für jeden Angestellten enthält

– Unterschiedliche Varianten der Organisation von Datensätzen in einer Datei • Beispiel: Sequenzielle Datei – Datensätze werden nach einem Schlüssel sortiert nacheinander gespeichert

• Datenbank – Aus einer Gruppe zusammengehöriger Dateien zusammengesetzt – Verwaltet durch eine Gruppe von Programmen, die zusammen Datenbank Management System (DBMS) genannt werden  2006 Pearson Education, Inc. All rights reserved.

7

Fig. 9.1 Datenhierarchie.

 2006 Pearson Education, Inc. All rights reserved.

8

9.3 Dateien und Ströme • Datei – C betrachtet jede Datei als eine Folge von Bytes (Fig. 9.2). – Jede Datei endet entweder mit einem ‘end-of-file marker’ oder an einer speziellen Byte-Nummer, die in einer systeminternen, administrativen Datenstruktur steht. – Wenn eine Datei geöffnet wird, wird ein Strom (‘stream’) mit ihr verbunden. – Drei Dateien und die mit ihnen assoziierten Ströme werden automatisch geöffnet, wenn die Programmausführung beginnt: standard input, standard output und standard error. – Ströme stellen Kommunikationskanäle zwischen Dateien und Programmen zur Verfügung.

 2006 Pearson Education, Inc. All rights reserved.

9

Fig. 9.2 | C-Sicht einer Datei mit n Bytes.

 2006 Pearson Education, Inc. All rights reserved.

10

9.3 Dateien und Ströme • Der Standardeingabestrom ermöglicht es einem Programm Daten von der Tastatur zu lesen und der Standardausgabestrom ermöglicht es einem Programm Daten auf den Bildschirm zu schreiben. • Das Öffnen einer Datei gibt einen Zeiger auf eine FILE Struktur (definiert in ) zurück, die Informationen zur Bearbeitung der Datei enthält. • standard input, standard output und standard error werden über die Dateizeiger stdin, stdout und stderr angesprochen.

 2006 Pearson Education, Inc. All rights reserved.

11

9.3 Dateien und Ströme • Die Standardbibliothek stellt viele Funktionen für das Lesen aus Dateien und das Schreiben in Dateien zur Verfügung. • Die Funktion fgetc liest ein einzelnes Zeichen aus einer Datei. Sie erwartet einen FILE Zeiger für die Datei, aus der das Zeichen gelesen werden soll, als Argument. • Der Aufruf fgetc( stdin ) liest ein Zeichen von stdin (der Standardeingabe). Dies ist äquivalent mit dem Aufruf getchar().

 2006 Pearson Education, Inc. All rights reserved.

12

9.3 Dateien und Ströme • Die Funktion fputc schreibt ein einzelnes Zeichen in eine Datei. Sie erwartet das zu schreibende Zeichen und einen FILE Zeiger für die Datei, in die das Zeichen geschrieben werden soll, als Argument. • Der Aufruf fputc( 'a', stdout ) schreibt das Zeichen 'a' nach stdout (der Standardeingabe). Dies ist äquivalent mit dem Aufruf putchar( 'a' ).

 2006 Pearson Education, Inc. All rights reserved.

13

9.3 Dateien und Ströme • Viele andere Funktionen, die Daten von Ein- und Ausgabe lesen bzw. schreiben, haben gleichartig benannte Dateiverarbeitungsfunktionen. • So können beispielsweise die Funktionen fgets und fputs benutzt werden, um eine Zeile aus einer Datei zu lesen bzw. eine Zeile in eine Datei zu schreiben. • In den nächsten Abschnitten werden die dateiverarbeitenden Äquivalente der Funktionen scanf und printf verwendet: fscanf und fprintf.

 2006 Pearson Education, Inc. All rights reserved.

14

9.4 Erzeugung einer sequenziellen Datei • Die struct FILE enthält die nötigen Informationen um mit einer Datei zu arbeiten: typedef struct { short levelOfBuffer; short validityToken; short bufferSize; char fileDescriptor; unsigned fileStatusFlags; unsigned char hold; unsigned char* buffer; unsigned char* currentActivePointer; unsigned tempFileIndicator; } FILE;  2006 Pearson Education, Inc. All rights reserved.

15

Praxistipp Die Definition der Struktur FILE ist nicht standardisiert und kann unterschiedlich implementiert sein. Man sollte deshalb nicht versuchen, direkt auf die Elemente von FILE zuzugreifen, sondern nur über die entsprechenden Funktionen mit FILE arbeiten (wie z.B. fopen, fprintf, fscanf, usw.).

 2006 Pearson Education, Inc. All rights reserved.

16

9.4 Erzeugung einer sequenziellen Datei • Öffnen einer Datei zur Ausgabe – Ein C Programm verwaltet jede Datei mit einer separaten FILE Struktur (deklariert in stdio.h). – Hierzu wird einer Variablen vom Typ FILE* durch die Funktion fopen ein Zeiger auf die FILE Struktur der zu öffnenden Datei zugewiesen. – fopen übernimmt zwei Argumente: Einen Dateinamen (einschließlich Pfadinformation zum Ort der Datei im Dateiverzeichnis) und einen Dateiöffnungs-Modus. – Der Dateiöffnungs-Modus "w" zeigt an, dass die Datei zum Schreiben geöffnet wird. – Falls die Datei nicht existiert und zum Schreiben geöffnet wird, erzeugt fopen die Datei.

 2006 Pearson Education, Inc. All rights reserved.

17

Modus

Beschreibung

r w

Öffnet eine vorhandene Datei zur Eingabe. Erzeugt eine Datei zur Ausgabe. Falls die Datei schon existiert, wird der vorhandene Inhalt verworfen.

a

Öffnet oder erzeugt eine Datei für die Ausgabe ans Ende der Datei.

r+ w+

Öffnet eine vorhandene Datei zur Aktualisierung (Ein- und Ausgabe). Erzeugt eine Datei zur Aktualisierung. Falls die Datei schon existiert, wird der vorhandene Inhalt verworfen. Öffnet oder erzeugt eine Datei zur Aktualisierung. Geschrieben wird am Ende der Datei.

a+ rb, wb, ab, rb+, wb+, ab+

Gleiche Funktionsweise wie oben beschrieben, jedoch nicht im Text-, sondern im Binärmodus.

Fig. 9.5 | Dateiöffnungsarten.

 2006 Pearson Education, Inc. All rights reserved.

18

9.4 Erzeugung einer sequenziellen Datei • Verwendung des FILE-Zeigers – In die Datei schreiben • Z.B. formatiertes Schreiben unter Verwendung der Funktion fprintf , die den FILE-Zeiger als erstes Argument übernimmt.

– Datei schließen • Funktion fclose • Übernimmt den FILE-Zeiger als einziges Argument • Gibt die Datei wieder frei

 2006 Pearson Education, Inc. All rights reserved.

19

Tipp zur Performanz Wenn ein Programm eine Datei nicht länger benötigt, sollte sie durch einen Aufruf von fclose explizit freigegeben werden.

 2006 Pearson Education, Inc. All rights reserved.

20

9.4 Erzeugung einer sequenziellen Datei • Test auf Dateiende mit feof – Die Funktion feof testet, ob der end-of-file Indikator für die Datei, deren FILE-Zeiger sie übernimmt, gesetzt ist. – Der end-of-file Indikator informiert das Programm, dass keine Daten mehr zu verarbeiten sind. – Auch stdin kann auf end-of-file getestet werden; das ‘Dateiende’ wird dann durch eine spezielle Tastenkombination simuliert. – Fig. 9.6 zeigt die Tastenkombinationen um end-of-file einzulesen für verschiedene Betriebssysteme.

 2006 Pearson Education, Inc. All rights reserved.

21

Plattform

Tastenkombination

UNIX/Linux/Mac OS X

(in einer eigenen Zeile)

Microsoft Windows

(manchmal mit zusätzlichem Enter)

VMS



Fig. 9.6 | Simulation der EOF-Markierung durch Tastatureingaben.

 2006 Pearson Education, Inc. All rights reserved.

22

9.4 Erzeugung einer sequenziellen Datei • Formatiertes Schreiben mit fprintf – Zum formatierten Schreiben in eine Datei wird die Funktion fprintf verwendet. – fprintf ist äquivalent mit printf, bis auf die Tatsache, dass fprintf einen Zeiger auf die zu schreibende Datei als erstes Argument übernimmt. – Bei Erfolg gibt fprintf (wie auch printf) die Gesamtzahl der erfolgreich geschriebenen Zeichen zurück. – Im Fehlerfall wird der Fehlerindikator für den Dateistrom gesetzt und eine negative Zahl zurückgegeben.

 2006 Pearson Education, Inc. All rights reserved.

1

// Fig. 9.4: fig09_04.c

2

// Creating a sequential file.

3

#include

4

#include // exit

5

#define NAME_SIZE 30

Outline

6 7

int main( void )

8

{

fig09_04.c

(1 von 2)

9

unsigned int account;

10

char name[ NAME_SIZE ];

11 12

double balance;

13

FILE* cfPtr = fopen( "clients.txt", "w" );

14

if( cfPtr == NULL ) {

Öffnen der Datei clients.txt zur Ausgabe fopen gibt NULL zurück, falls die Datei nicht erfolgreich geöffnet wurde

15

fputs( "File could not be opened", stderr );

16

exit( 1 ); // exit program if unable to create file

17

23

} // end if

18 19

puts( "Enter the account, name, and balance." );

20

printf( "%s", "Enter EOF to end input.\n? " );

21

scanf( "%d%29s%lf", &account, name, &balance );

22

feof gibt 1 zurück, wenn der Nutzer EOF eingibt

23

// write account, name and balance into file with fprintf

24

while( ! feof( stdin ) ) {

25

fprintf( cfPtr, "%d %s %.2f\n", account, name, balance );

26

printf( "%s", "? " );

27

scanf( "%d%29s%lf", &account, name, &balance );

28

} // end while

29 30

Formatierte Ausgabe in clients.txt mit fprintf

fclose schließt die Datei

fclose( cfPtr ); // closes file

31 } // end main

 2006 Pearson Education, Inc. All rights reserved.

Enter Enter ? 100 ? 200 ? 300 ? 400 ? 500 ? ^Z

the account, name, and balance. EOF to end input. Jones 24.98 Doe 345.67 White 0.00 Stone -42.16 Rich 224.62

Outline

24

fig09_04.c

(2 von 2)

 2006 Pearson Education, Inc. All rights reserved.

9.5 Daten von einer sequenziellen Datei lesen

25

• Öffnen einer Datei zum Einlesen – Hierzu wird einer Variablen vom Typ FILE* durch die Funktion fopen ein Zeiger auf die FILE Struktur der zu öffnenden Datei zugewiesen. – fopen übernimmt zwei Argumente: Einen Dateinamen (einschließlich Pfadinformation zum Ort der Datei im Dateiverzeichnis) und einen Dateiöffnungs-Modus. – Der Dateiöffnungs-Modus "r" zeigt an, dass die Datei zum Lesen geöffnet wird. – Falls die Datei nicht existiert und zum Lesen geöffnet werden soll, gibt fopen den Wert NULL zurück.

 2006 Pearson Education, Inc. All rights reserved.

9.5 Daten von einer sequenziellen Datei lesen

26

• Formatiertes Einlesen mit fscanf – Zum formatierten Einlesen aus einer Datei wird die Funktion fscanf verwendet. – fscanf ist äquivalent mit scanf, bis auf die Tatsache, dass fscanf einen Zeiger auf die einzulesende Datei als erstes Argument übernimmt. – Bei Erfolg gibt fscanf (wie auch scanf) die Anzahl der erfolgreich gelesenen Argumente zurück. Dies kann der Anzahl der erwarteten Werte entsprechen oder kleiner sein aufgrund eines Lesefehlers oder des Erreichens von end-of-file (EOF). – Im Fehlerfall wird der passende Indikator (Fehler oder EOF) für den Dateistrom gesetzt und - falls dies vor dem erfolgreichen Einlesen von Daten passiert - EOF zurückgegeben.  2006 Pearson Education, Inc. All rights reserved.

1

// Fig. 9.7: fig09_07.c

2

// Reading and printing a sequential file.

3

#include

4

#include // exit function prototype

5

#define NAME_SIZE 30

Outline

6 7

int main( void )

8

{

fig09_07.c

(1 von 2)

9

unsigned int account;

10

char name[ NAME_SIZE ];

11 12

double balance;

13

FILE* cfPtr = fopen( "clients.txt", "r" );

Öffnen von clients.txt zum Einlesen

14 15

if( cfPtr == NULL ) {

fopen gibt NULL zurück, falls clients.txt nicht erfolgreich geöffnet werden konnte

16

fputs( "File could not be opened", stderr );

17

exit( 1 ); // exit program if file could not be opened

18

27

} // end if

19 20

printf( "%-10s%-13s%s\n", "Account", "Name", "Balance" );

21 22

// display each record in file

23 24

while( fscanf( cfPtr, "%d%29s%lf", &account, name, &balance ) == 3 ) printf( "%-10d%-13s%7.2f\n", account, name, balance );

25 26

fclose( cfPtr );

27 } // end main

fscanf gibt die Anzahl der erfolgreich eingelesenen Argumente zurück; wenn das Ende der Datei clients.txt erreicht wird, ist dieser Wert ungleich 3 und die Schleife wird beendet.  2006 Pearson Education, Inc. All rights reserved.

Account 100 200 300 400 500

Name Jones Doe White Stone Rich

Balance 24.98 345.67 0.00 -42.16 224.62

Outline

28

fig09_07.c

(2 von 2)

 2006 Pearson Education, Inc. All rights reserved.

9.5 Daten von einer sequenziellen Datei lesen

29

• Datei-Positionszeiger – Byte-Nummer des nächsten Byte zum Lesen oder Schreiben • Keine Variable eines Zeigertyps, sondern ein int-Wert

– Die Anweisung rewind( cfPtr );

setzt den Datei-Positionszeiger an den Anfang (d.h. Byte 0) der Datei, der cfPtr zugeordnet ist.

 2006 Pearson Education, Inc. All rights reserved.

9.5 Daten von einer sequenziellen Datei lesen

30

Kreditabfrage Programm • Das folgende Programm erlaubt es, Listen von – Kunden mit Kontostand Null, – Kunden mit Kreditstand (d.h. Kunden, denen das Unternehmen Geld schuldet) und – Kunden mit Debitstand (d.h. Kunden, die dem Unternehmen Geld für Waren und Dienstleistungen schulden)

auszugeben. • Ein Kreditstand ist ein negativer Wert; ein Debitstand ist ein positiver Wert.  2006 Pearson Education, Inc. All rights reserved.

1

// Fig. 9.8: fig09_08.c

2

// Credit inquiry program.

3

#include

4

#include // exit function prototype

5

#define NAME_SIZE 30

6 7

enum RequestType { ZERO_BALANCE = 1, CREDIT_BALANCE, DEBIT_BALANCE, END };

8 9

int main( void )

Outline

31

fig09_08.c

(1 von 3)

10 { 11

unsigned int request;

12

unsigned int account;

13

char name[ NAME_SIZE ];

14

double balance;

15 16

FILE* cfPtr = fopen( "clients.txt", "r" );

17 18

if( cfPtr == NULL ) {

19

fputs( "File could not be opened", stderr );

20

exit( 1 ); // exit program if file could not be opened

21

} // end if

22 23 24

// display request options printf( "%s", "\nEnter request\n"

25

" 1 - List accounts with zero balances\n"

26

" 2 - List accounts with credit balances\n"

27

" 3 - List accounts with debit balances\n"

28

" 4 - End of run\n? " );

29

scanf( "%u", &request );

30

 2006 Pearson Education, Inc. All rights reserved.

31

// process user's request

32

while( request != END ) {

33

switch( request ) {

34

case ZERO_BALANCE:

35

puts( "\nAccounts with zero balances:" );

36

// read and display file contents (until eof)

37

while( fscanf( cfPtr, "%d%29s%lf", &account, name, &balance ) == 3 )

38

if( balance == 0 )

39 40 41

printf( "%-10d%-13s%7.2f\n", account, name, balance );

43

// read and display file contents (until eof)

44

while( fscanf( cfPtr, "%d%29s%lf", &account, name, &balance ) == 3 )

45

if( balance < 0 )

46

printf( "%-10d%-13s%7.2f\n", account, name, balance ); break; case DEBIT_BALANCE:

49

puts( "\nAccounts with debit balances:" );

50

// read and display file contents (until eof)

51

while( fscanf( cfPtr, "%d%29s%lf", &account, name, &balance ) == 3 )

52 53 54

(2 von 3)

case CREDIT_BALANCE: puts( "\nAccounts with credit balances:" );

48

fig09_08.c

break;

42

47

Outline

32

if( balance > 0 ) printf( "%-10d%-13s%7.2f\n", account, name, balance ); break;

55

} // end switch

56

rewind( cfPtr ); // return cfPtr to beginning of file

57

printf( "%s", "\n? " );

58

scanf( "%u", &request );

59

} // end while

60

puts( "End of run." );

61

fclose( cfPtr ); // close file

62 } // end main

 2006 Pearson Education, Inc. All rights reserved.

Outline

Enter request 1 - List accounts with zero balances 2 - List accounts with credit balances 3 - List accounts with debit balances 4 - End of run ? 1

fig09_08.c

Accounts with zero balances: 400 Metzger 0.00

(3 von 3)

33

? 2 Accounts with credit balances: 300 Muller -112.00 ? 3 Accounts with debit balances: 100 Becker 99.90 200 Schneider 199.90 500 Schmidt 22.20 ? 4 End of run.

 2006 Pearson Education, Inc. All rights reserved.

34

9.6 Eine sequenzielle Datei aktualisieren • Aktualisierung eines Datensatzes in einer sequenziellen Datei – Der neue Datensatz könnte länger als der alte sein. • Falls dies so ist, werden Teile des nächsten sequenziellen Datensatzes überschrieben. • Um dies zu vermeiden, müssen alle Datensätze hinter dem neuen Datensatz kopiert werden. • Für große Dateien kann der entsprechende Aufwand unakzeptabel werden.

 2006 Pearson Education, Inc. All rights reserved.

35

9.7 Dateien mit wahlfreiem Zugriff • Dateien mit wahlfreiem Zugriff – Notwendig für Anwendungen mit direktem Zugriff • Beispielsweise Systeme zur Transaktionsverarbeitung

– Ein Datensatz kann eingefügt, gelöscht oder modifiziert werden, ohne andere Datensätze zu beeinflussen. – Verschiedene Techniken können eingesetzt werden. • Voraussetzung ist, dass alle Datensätze die gleiche Länge haben und in der Reihenfolge ihrer Schlüssel angeordnet sind. – Das Programm kann den genauen Ort jedes Datensatzes berechnen. • Basis hierfür sind Größe und Schlüssel des Datensatzes.

 2006 Pearson Education, Inc. All rights reserved.

36

Fig. 9.9 | C-Sicht einer Datei mit wahlfreiem Zugriff.

 2006 Pearson Education, Inc. All rights reserved.

9.8 Erzeugung einer Datei mit wahlfreiem Zugriff

37

• Die Funktion fwrite schreibt eine bestimmte Anzahl von Bytes, beginnend an einer bestimmten Speicheradresse, unformatiert in eine Datei. • Die Daten werden in der Datei ab der Stelle geschrieben, auf die der Dateipositions-Zeiger gerade zeigt. • Entsprechend liest die Funktion fread eine bestimmte Anzahl von Bytes ab der Stelle in der Datei, auf die der Dateipositions-Zeiger gerade zeigt, in einen Speicherbereich beginnend an einer angegebenen Speicheradresse.

 2006 Pearson Education, Inc. All rights reserved.

9.8 Erzeugung einer Datei mit wahlfreiem Zugriff

38

•Funktion fwrite – Schreibt eine Anzahl von Bytes aus einem Speicherbereich in eine Datei an die Stelle, auf die der Positionszeiger zeigt. – Parameter: • Ein const void*, der auf das Anfangsbyte eines Arrays im Speicher zeigt • Ein size_t, der die Anzahl der Bytes angibt, die für ein Element des Arrays geschrieben werden sollen • Ein size_t, der die Anzahl der Elemente im Array angibt, die geschrieben werden sollen • Zeiger auf eine FILE-Struktur, die die Ausgabedatei angibt

– Beispiel: fwrite( &number, sizeof( int ), 1, fPtr );  2006 Pearson Education, Inc. All rights reserved.

39

Portabilitäts-Tipp Die Verwendung von fwrite ist systemabhängig und kann dazu führen, dass sich Programme auf verschiedenen Plattformen unterschiedlich verhalten. Die Daten werden nicht formatiert (wie im Fall von fprintf ), sondern in Form von ‘rohen Daten’ (also als Bytes) geschrieben.

 2006 Pearson Education, Inc. All rights reserved.

40

Portabilitäts-Tipp Ein Programm, das unformatierte Daten liest (die mit fwrite geschrieben wurden), muss auf einem System kompiliert und ausgeführt werden, das mit dem Programm kompatibel ist, das die Daten geschrieben hat. Unterschiedliche Systeme können unterschiedliche interne Datendarstellungen verwenden (Beispiel: Big Endian – Little Endian).

 2006 Pearson Education, Inc. All rights reserved.

9.8 Erzeugung einer Datei mit wahlfreiem Zugriff

41

• Headerdateien – Separate Dateien, die nur Typdefinitionen, Funktionsprototypen und Konstanten enthalten • Erlauben dem Compiler nutzerdefinierte Typen und Funktionen zu erkennen, wenn sie anderswo eingesetzt werden

– Haben im allgemeinen .h Erweiterung für Dateinamen

• Testanwendungsdateien (Driver files) – Programme zum Testen von Typen und Funktionen – Enthalten eine main Funktion und sind ausführbar – Haben im allgemeinen .c Erweiterung für Dateinamen

•.h und .c Dateien werden als Quelldateien

(source code files) bezeichnet .

 2006 Pearson Education, Inc. All rights reserved.

9.8 Erzeugung einer Datei mit wahlfreiem Zugriff

42

• #include Präprozessor-Direktive – Wird benutzt, um Headerdateien einzufügen • Weist den C Präprozessor an, die Direktive durch eine Kopie des Inhalts der angegebenen Datei zu ersetzen

– Anführungszeichen kennzeichnen eine nutzerdefinierte Headerdatei • Der Präprozessor sucht zuerst im aktuellen Verzeichnis – Falls die Datei nicht gefunden wird, sucht er im C Standard-include-Verzeichnis

– Winkelklammern kennzeichnen die C Standardbibliothek • Präprozessor sucht nur im C Standard-include-Verzeichnis

 2006 Pearson Education, Inc. All rights reserved.

9.8 Erzeugung einer Datei mit wahlfreiem Zugriff

43

• Präprozessordirektiven zur Vermeidung des mehrfachen Einbindens von Headerdateien – Verhindern, dass Code mehr als einmal eingebunden wird • #ifndef – “if not defined”

– Überspringe diesen Code, falls schon definiert, d.h. eingebunden • #define

– Definiere einen Namen zur Vermeidung des nochmaligen Einbindens • #endif

– Falls der Header schon zuvor eingebunden wurde • Name ist schon definiert und Headerdatei wird nicht mehr eingebunden

– Verhindert Fehlermeldungen durch Mehrfachdefinitionen – Beispiel: #ifndef CLIENTDATA_H #define CLIENTDATA_H … // code #endif  2006 Pearson Education, Inc. All rights reserved.

9.8 Erzeugung einer Datei mit wahlfreiem Zugriff

44

• Aufgabenstellung: – Es soll ein Kreditverarbeitungs-Programm geschrieben werden, das bis zu 100 Datensätze fester Länge in einer Datei speichern kann. Jeder Datensatz soll aus einer Kontonummer (die auch als Schlüssel für den Datensatz dient), Nachname, Vorname und Kontostand bestehen. – Das Programm soll • ein bestehendes Konto aktualisieren können, • einen Datensatz für ein neues Konto einfügen können, • ein Konto löschen und • die Datensätze aller vorhandenen Konten als formatierte Textdatei abspeichern oder auf die Konsole ausgeben können.

– Es soll eine Datei mit wahlfreiem Zugriff verwendet werden.  2006 Pearson Education, Inc. All rights reserved.

9.8 Erzeugung einer Datei mit wahlfreiem Zugriff

45

– Das Kreditverarbeitungs-Programm wird in mehreren Schritten / Teilprogrammen entwickelt. – Das erste Teilprogramm dient nur dazu, die Grundstruktur der verwendeten Datei zu erzeugen, indem 100 leere Datensätze erzeugt und in eine Datei mit wahlfreiem Zugriff geschrieben werden. – Die Datensätze werden als Variablen vom Typ einer struct Clientdata erzeugt.

 2006 Pearson Education, Inc. All rights reserved.

1

// Fig. 9.11: ClientData.h

2

// Type ClientData definition used in Fig. 9.12 – Fig. 9.15.

3

#ifndef CLIENTDATA_H

4

#define CLIENTDATA_H

5 6

typedef struct {

7

unsigned int accountNumber;

8

char lastName[ 16 ];

9

char firstName[ 12 ];

10

double balance;

Headerdatei, die die Definition des Typs ClientData enthält.

Outline

46

ClientData.h

(1 von 1)

11 } ClientData; // end definition of type ClientData 12 13 #endif

 2006 Pearson Education, Inc. All rights reserved.

1

// Fig. 9.12: fig09_12.c

2

// Creating a random-access file sequentially.

3

#include

4

#include // exit

5

Outline

Einfügen der Headerdatei, die die Definition des Typs ClientData enthält.

#include "ClientData.h" // Definition of type ClientData

fig09_12.c

8

int main( void )

(1 von 1)

9

{

6

47

7

10

size_t i; // loop counter

11

ClientData blankClient = { 0, "", "", 0.0 }; // default record

12 13

FILE* cfPtr = fopen( "credit.dat", "wb" );

credit.dat im Binärmodus öffnen

14 15

if( cfPtr == NULL ) {

16

fputs( "File could not be opened.", stderr );

17

exit( 1 ); // exit program if unable to open file

18

} // end if

19 20

// output 100 blank records to file

21

for( i = 0; i < 100; ++i )

22

fwrite( &blankClient, sizeof( ClientData ), 1, cfPtr );

23 24

fclose( cfPtr );

25

fputs( "File written." );

26 } // end main

Daten in blankClient als Bytes in credit.dat abspeichern

 2006 Pearson Education, Inc. All rights reserved.

9.9 Daten wahlfrei in eine Datei mit wahlfreiem Zugriff schreiben

48

• Daten an bestimmte Position schreiben – Für Ein- und Ausgabe im Binärmodus öffnen • Verwenden der Dateiöffnungsart "rb+"

– Einsatz der Funktion fseek, um den Positionszeiger an die gewünschte Position zu setzen • Beispiel: ( n – 1 ) * sizeof( ClientData ) • Byteposition für nten ClientData Datensatz

– Verwendung von fwrite, um Daten zu schreiben

 2006 Pearson Education, Inc. All rights reserved.

1

// Fig. 9.13: fig09_13.c

2

// Writing data randomly to a random-access file.

3

#include

4

#include // exit

Outline

49

5 6

#include "ClientData.h" // ClientData type definition

fig09_13.c

8

int main( void )

9

{

(1 von 3)

7

10

ClientData client = { 0, "", "", 0.0 }; // default record

11 12

FILE* cfPtr = fopen( "credit.dat", "rb+" );

13 14

if( cfPtr == NULL ) {

15

fputs( "File could not be opened.", stderr );

16

exit( 1 ); // exit program if unable to open file

17

Verwenden von rb+, um credit.dat zur Ein- und Ausgabe im Binärmodus zu öffnen

} // end if

18 19

// require user to specify account number

20

printf( "%s", "Enter account number (1 to 100, 0 to end input)\n? " );

21

scanf( "%d", &client.accountNumber );

 2006 Pearson Education, Inc. All rights reserved.

22 23

// user enters information, which is copied into file

24

while( client.accountNumber > 0 && client.accountNumber

Suggest Documents