PurePascal (7)

In dieser Folge des Kurses wird das Kapitel 7.2 "Strukturierte Datentypen" fortgesetzt, in dem in der letzten Ausgabe schon die Datenstrukturen Zeichenkette STRING und Feld ARRAY behandelt worden sind.

7.2.3 Datenstruktur Menge SET

Eine Menge besteht immer aus einer bestimmten Anzahl von Elementen eines abzählbaren Datentyps. Mit der Datenstruktur Menge (SET) können Programme leicht gegen Eingabefehler abgesichert werde, indem die Eingabe mit der vereinbarten Menge überprüft wird. Eine Menge kann direkt oder über einer Mengenvariable in ein Programm eingebracht werden.

Beispiel;

repeat
  gotoxy(20,12); clreol;
  readln(Stufe);
  if not Stufe in [l, 3, 5, 7] then 
     writeln('Eingabefehler!'); 
until Stufe in [l, 3, 5, 7];

In dem Beispiel wird zuerst der Cursor in Zeile 20 Spalte 12 gesetzt (gotoxy (20,12);) und die Zeile ab der Cursorposition bis zum Zeilenende gelöscht (clreol;). Danach erfolgt an der Cursorposition die Eingabe für die Variable "Stufe". Wird eine andere Eingabe getätigt als eine l, 3, 5 oder 7, so wird der Text "Eingabefehler!" ausgegeben. Die Eingabe wird in der Schleife solange wiederholt, wie ein falscher Wert eingegeben wurde. Der Vergleichsoperator für eine Menge ist in diesem Fall das Wort in. Die direkte

Menge wird in eckigen Klammern geschrieben und deren Elemente durch ein Komma getrennt.

Mengenvariablen werden wie andere Variablen vereinbart (die beiden Vereinbarungen für sind MAXZAHL hierbei identisch):

var Zahll : set of 0..100;
Zeichen : set of char;
Grossbu : 'A'..'Z';
MAXZAHL : set of byte;
MAXZAHL : set of 0..255;

Den Variablen lassen sich Bereichswerte zuweisen:

Zahll := [UW..OW];

Beträgt der Unterwert UW =1 und der Oberwert OW=8, dann ist die Menge der Elemente: 1,2,3,4,5,6,7,8.

Übersicht l

var Verbundvariable : record
         Komponentel : Datentyp;
         Komponente2 : Datentyp;
         Komponente3 : Datentyp;
      end;

Das könnte für den Verein heißen:

var MITGLIED : record
               Mitgliednr : integer;
               Name : string[30];
               Vorname : string[29];
               Ort : string[30];
               Strasse : string[30];
               Sparte1 : string[15];
               Sparte2 : string[15];
               Eintritt : longint;
               Beitrag : integer; 
        end;

Die Prüfung auf ein Element findet, wie oben schon erwähnt, mit dem Operator in statt:

    until Wert in Zahll;

In PurePascal dürfen Mengen nicht mehr als 256 Elemente beinhalten. Für Mengen stehen die Mengenoperationen Vereinigung +, Durchschnittsmenge * und Uiffe-renzmenge - zur Verfügung. Außer dem Operator in sind die logischen Operatoren =, <=, >= und <> verwendbar.

7.2.4 Datenstruktur Verbund RECORD

Halten wir uns einen Sportverein vor Augen. Die Daten der einzelnen Mitglieder sind in der Datenverarbeitungsanlage gespeichert. Zu jedem Mitglied gehört immer ein fest zugeordneter Satz von Daten:

Dieser Datensatz ist jedem Mitglied zugeordnet. Dabei soll es so sein, daß die Daten nicht aus vielen Feldern zusammengesucht werden sollen, sondern alle Daten stehen z.B. über die Mitgliedsnummer zur Verfügung. Die Datenstruktur Verbund (RECORD) gestattet es, Variablen (Komponenten) unterschiedlichen Datentyps zu einer neuen Einheit zusammenzufassen. Die Vereinbarung sieht wie folgt aus: Zugriff auf eine Komponente: Es sind im Beispiel zwei Stufen von Namen vergeben worden: der Name der Verbundvariablen (hier: MITGLIED ) und die Komponentennamen des Verbundes (z.B. Mitgliednr). Der Aufruf heißt dann:

readln (Mitglied.Mitgliednr);

Jede Komponente kann also mit dem zweiteiligen Namen aufgerufen werden. Wird mit den Variablen eines records gearbeitet, kann die Zuweisung mit der WITH-Anweisung vereinfacht werden, weil nur noch der Komponentenname benötigt wird (Beispiel 1). Zu beachten ist, daß wenn eine Variable vom Typ RECORD oder ARRAY komplett auf eine andere Variable übertragen wird, beide Variablen genau dieselbe Datenstruktur aufweisen müssen!

7.2.5 Datenstruktur sequentielle Datei FILE

Die Datensätze, die im vorigen Abschnitt erstellt wurden, sind spätestens mit dem Ausschalten des Rechners verloren. Es muß also eine Möglichkeit geben, die Daten auf Datenträgern (Diskette und Festplatte) dauerhaft zu sichern, d.h. die Daten werden auf externe Datenträger übertragen. Dafür stellt Pascal die Datenstruktur Datei (FILE) zur Verfügung.

7.2.5.1 Vereinbaren einer Datei

Beispiele
Beispiel 1:

with Mitglied do 
    begin
        write('Bitte Namen eingeben: '); readln (Name); 
        write('Bitte Vornamen eingeben: '); readln (Vorname); 
        write('Bitte Wohnort eingeben: '); readln(Ort);
        ...
    end; 
Beispiel 2:
var Vereinsdatei : file of MITGLIED;

Der Datentyp Mitglied ist z.B. als record typisiert worden:

type MITGLIED = record
       Mitgliednr : integer;
       Name       : string[30];
       Vorname    : string[29];
       ...
     end;

Es muß eine Dateivariable vereinbart werden (siehe Beispiel 2). Danach wird dem logischen Namen MITGLIED noch ein physischer Name auf der Diskette oder Festplatte zugeordnet:

    assign (Vereinsdatei, 'A:mitglied.dat');

Die Datei ist auf der Diskette im Laufwerk A: unter dem Namen "mitglied.dat" zu finden. Es muß ein gültiger Name vereinbart sein, d.h. maximal 8 Zeichen vor dem Punkt und maximal 3 danach und keine Verwendung von Sonderzeichen und Umlauten.

7.2.5.2 Öffnen einer Datei

Eine Datei öffnen heißt, der Zeiger zeigt auf den ersten Datensatz der mit dem Namen vereinbarten Datei. Pascal bietet 2 Prozeduren dafür:

    rewrite (Vereinsdatei);

Mit rewrite legt man auf dem vorher mit assign vereinbarten externen Dateiträger eine Datei mit dem angegebenen Namen an. Der Zeiger zeigt auf den ersten Datensatz, die Datei ist zur Aufnahme von Datensätzen bereit.

ACHTUNG!

Sind der mit assign vereinbarte Dateiname und ein auf dem externen Datenträger schon vorhandener Dateiname gleich, so wird die Datei auf dem externen Datenträger gelöscht! Ohne Hinweis und ohne Fehlermeldung!!!

    reset (Vereinsdatei);

Ist eine Datei bereits eingerichtet, wird der Zeiger mit reset auf den ersten Datensatz gestellt. In der Datei kann nun gelesen und/oder geschrieben werden. Existiert die vereinbarte Datei auf dem externen Datenträger nicht, wird das Programm abgebrochen.

7.2.5.3 Schreiben in eine Datei

In eine Datei schreiben heißt, ein gefüllter Datensatz wird auf dem externen Datenträger abgelegt.

    write (Vereinsdatei, MITGLIED);

Beim Schreiben muß nicht immer der gesamte Datensatz abgespeichert werden. In einem Zwischenspeicher (Buffer) wird der abzulegende Datensatz in festen Paketen auf der Platte abgelegt, so daß erst mit dem Schließen der Datei auch der "Rest" zugewiesen wird.

7.2.5.4 Lesen aus einer externen Datei

    read (Vereinsdatei, MITGLIED);

Mit read wird ein Datensatz in den Hauptspeicher eingelesen und der Zeiger für den nächsten Lesevorgang auf den folgenden Datensatz gestellt. Mit jedem Lesevorgang wird der Zeiger um einen Datensatz weiter gesetzt. Der Lesevorgang kann solange fortgesetzt werden, bis die Datei-ende-Marke (EOF-Marke) erreicht ist.

7.2.5.5 Schließen einer Datei

Jede geöffnete Datei muß auch wieder geschlossen werden, damit der Diskettenoder Festplattenzugriff korrekt abgeschlossen werden kann. Jeder Schreib-Lese-Vorgang erfolgt über einen Pufferspeicher, der ohne ein korrektes Abschließen noch Daten enthalten kann.

    close (Vereinsdatei);

Beispiele

procedure DateiOeffnen (var VDatei : MITGLIED);
begin

(*$I-*) {Prüfung der Ein-Ausgabe abschalten)
    reset(VDatei);
    if ioresult<>0 then
       rewrite(VDatei); {Datei nicht vorhanden}
    if ioresult<>0 then

       begin       {Es liegt ein anderer Fehler vor, z.B.}
          writeln; {könnte der Datenträger voll sein.} 
          write ('Datei kann nicht geöffnet werden!'}; 
          delay(lOOO);
          halt; {Programmabbruch}
      end;
   (*$I+*) {Prüfung der Ein-Ausgabe einschalten}
end;

7.2.5.6 Allgemeine Datei-Öffnungsprozedur

Eine vorhandene Datei darf nicht gelöscht werden. Man "tastet" sich mit der reset-Anweisung heran und riskiert einen Programmabsturz, der abgefangen werden kann (Die Variable ioresult wird automatisch vom Compiler angelegt.):

7.2.5.7 Positionierung in einer Datei

Pascal stellt eine Prozedur und zwei Funktionen zur Verfügung, die die Positionierung des Zeigers auf einen Datensatz (Datum) innerhalb einer geöffneten Datei ermöglichen.

a) Standardfunktion FILESIZE
Die Standardfunktion FILESIZE liefert die Größe einer Datei zurück, also die Anzahl der Datensätze in der angegebenen Datei. Ist die Datei leer, wird der Wert ’0’ zurückgegeben.

   Anzahl := filesize(Vereinsdatei);

In der Variablen Anzahl wird die zurückgegebene Größe der Datei Vereinsdatei abgelegt.

b) Standardfunktion FILEPOS
Die Standardfunktion FILEPOS liefert die momentane Position des Zeigers in der geöffneten Datei zurück - die Position des nächsten zu bearbeitenden Datensatzes.

   Position := filepos(Vereinsdatei};

In der Variablen Position ist die Nummer des Satzes abgelegt, auf den der Zeiger gerade zeigt. Die Durchnumerierung in der Datei beginnt mit '0'.

c) Standardprozedur SEEK
Um den Zeiger auf einen bestimmten Datensatz zu positionieren, wird die Standardprozedur SEEK eingesetzt. Dazu sind die Parameter "Dateiname" und "Satznummer" anzugeben. Es ist zu beachten, daß der erste Datensatz die Nummer '0' hat.

   seek(Vereinsdatei, 0);

Dieser Prozeduraufruf setzt die Datei Vereinsdatei auf den Anfang zurück.

d) Typische Anwendungen
Setzen des Zeigers an das Ende der geöffneten Datei. Dafür erhält SEEK den Dateinamen und den Rückgabewert der Funktion FILESIZE:

   Anzahl := filesize(Vereinsdatei); 
   seek(Vereinsdatei, Anzahl);

oder

   seek(Vereinsdatei, filesize(Vereinsdatei));

Nach dem Lesen eines Datensatzes soll der geänderte Datensatz an die alte Position geschrieben werden. Der Zeiger steht zu diesem Zeitpunkt bereits auf dem folgenden Satz, er muß also um eine Einheit zurückgesetzt werden:

   Position := filepos(Vereinsdatei); 
   seek(Vereinsdatei, Position - 1);

oder

   seek(Vereinsdatei, filepos(Vereinsdatei) - 1);

7.2.6 Datenstruktur Textdatei

Standen bei der Datenstruktur FILE das Speichern und die Bearbeitung von satzorientierten Informationen (immer die gleiche Länge) im Vordergrund, so ist die Textverarbeitung viel einfacher, da der eingegebene Text mit jedem Drücken der Eingabetaste - sie erzeugt ein Zeilenende (EOL) - in die vereinbarte Datei geschrieben wird.

Da die gespeicherten Texte unterschiedliche Länge haben, ist klar, daß nur geschrieben oder (im Folgendem) nur gelesen werden kann.

Die Vereinbarung des Dateinamens, der Datentyp ist hier text (-Datei):

   var Dateiname : text;

Die assign -Anweisung ist schon von der Datenstruktur FILE her bekannt:

   assign (Dateiname, Physische Datei);

Die neue Datei wird zum Schreiben geöffnet:

   rewrite (Dateiname);

Die Eingabe, die mit EOL (Betätigen von ENTER) abgeschlossen wurde, wird über den Pufferspeicher auf dem Datenträger abgelegt. So können beliebig viele Eingaben behandelt werden. Mit EOF (Dateiende, Control + Z) wird die Eingabe beendet:

   writeln (Dateiname, Zeichenkette);

Schließen der Datei: Mögliche Datenreste aus dem Pufferspeicher und das EOF-Zeichen werden zur Vervollständigimg des Datenbestandes übertragen und die "Verbindung" beendet:

   close (Dateiname);

Die vorhandene Datei zum Lesen öffnen:

   reset (Dateiname);

Einlesen einer Textzeile in die Variable Textvariable.

   readln (Dateiname, Textvariable);

In der nächsten, letzten Folge dieses Kurses werden die dynamischen Datentypen behandelt. Dort lernen Sie dann etwas über Zeigervariablen und verkettete Listen.

7.2.5.8 Von Pascal unterstützte DOS-Systemaufrufe

Zur Unterstützung von Zugriffen auf das Dateisystem sind in PurePascal DOS-Prozeduren und -Funktionen enthalten:

a) für einzelne Dateien
- Datei löscht: erase(Dateivariable);
- Datei umbenennen: rename(Dateivariable, physischer Dateiname1);

b) für Verzeichnisse:
- Verzeichnis wechseln: chdir(Verzeichnisname);
- Verzeichnis erstellen: mkdir(Unterverzeichnisname);
- Verzeichnis löschen: rmdir(Unterverzeichnisname);

c) für Parameter der Laufwerke:
- freier Laufwerksplatz: diskfree(Laufwerk);
- Laufwerksgröße: disksize(Laufwerk);

d) für den Einsatz der Systemdaten für Datum und Zeit:
- Systemdatum ermittein: getdate(Jahr, Monat, Tag, Wochentag);
- Systemzeit ermitteln: gettime(Stunde, Minute, Sekunde, Sek100);
- Systemdatum setzen: setdate(Jahr, Monat, Tag, Wochentag);
- Systemzeit setzen: settime(Stunde, Minute, Sekunde, Sek100);

Beispiele
Texte eingeben und auf Diskette ablegen:

program Texterfassung; 
 uses crt;
 var Textzeile: string[80]; 
     Textdatei: text;

 begin

     clrscr;
     assign(Textdatei, 'a:textOl.txt'); 
     rewrite{Textdatei); 
     checkeof = true;
     writeln('Bitte Texte eingeben und jede Zeile mit ENTER beenden.');
     writeln('Beenden mit Contrl+Z'); 
     writeln;
     while not EOF do 
         begin
             readln(Textzeile); 
             writeln(Textdatei, Textzeile); 
         end;
     close (Textdatei); 
end.


Torsten Runge
Links

Copyright-Bestimmungen: siehe Über diese Seite
Classic Computer Magazines
[ Join Now | Ring Hub | Random | << Prev | Next >> ]