______________________________________________________________

Aufgabe 6.1
___________
Quelltext:

MODULE CD EXPORTS Main;
IMPORT IO, FileRd, Rd, FileWr, Wr, Text, Pathname, OSError, Thread;

TYPE
  CD = RECORD interpret, titel, label, srnr : TEXT;
  END;
VAR Wahl : CHAR;
VAR neueCD : CD;
VAR Channel : Wr.T;
VAR Pfad : Pathname.T;
VAR RdChannel : Rd.T;
VAR Line : TEXT;
VAR Von, Bis : INTEGER;

(*********************************************************************)
(* Programm 'CD' liest durch Semikolon getrennte Datensaetze aus     *)
(* Textdateien aus, bzw. schreibt solche zurueck.                    *)
(*********************************************************************)

BEGIN

(* Zieldatei abfragen und versuchen, diese zu oeffnen. Abbruch bei Fehler. *)
  LOOP
    IO.Put("Bitte geben sie den Namen der Zieldatei an:\n");
    Pfad:= IO.GetLine();
    (* Versuch, die Datei zu oeffnen. *)
    TRY
      Channel:= FileWr.OpenAppend(Pfad);
      Wr.Close(Channel);
      EXIT
    EXCEPT
    (* Abbruch bei Fehler. *)
      | Wr.Failure => IO.Put("\nKann Datei nicht oeffnen! Wiederholen [j/n]");
        Wahl:= IO.GetChar();EVAL IO.GetLine();
        IF Wahl#'J' AND Wahl#'j' THEN Wahl:='4'; EXIT; END;
      | OSError.E => IO.Put("\nKann Datei nicht oeffnen! Wiederholen [j/n]");
        Wahl:= IO.GetChar();EVAL IO.GetLine();
        IF Wahl#'J' AND Wahl#'j' THEN Wahl:='4'; EXIT; END;
      | Thread.Alerted => Wahl:='4'; EXIT;
    END;
  END;

  (* Anzeigen des Menues, Dateioperationen abhaengig von Benutzerwahl *)
  (* ausfuehren.                                                      *)
  LOOP
    IF Wahl= '4' THEN EXIT; END; (* Abbruch, wenn gewaehlt. *)

    IO.Put("\n[1] Eingabe eines neuen Datensatzes\n");
    IO.Put("[2] Anzeigen des CD-Bestandes\n");
    IO.Put("[3] Loeschen aller Datensaetze\n");
    IO.Put("[4] Beenden des Programms\n");

    Wahl:= IO.GetChar();
    EVAL IO.GetLine();

    (**Ereignisbehandlung**)
    (* Wenn '1', dann Werte einlesen und Datensatz hinzufuegen.   *)
    (* Wenn '2', Datensatz auslesen und zuweisen. Werte ausgeben. *)
    (* Wenn '3', Dateiinhalt loeschen.                            *)
    CASE Wahl OF
    | '1' =>
      IO.Put("\nBitte geben sie den Interpreten an:  ");
      neueCD.interpret:= IO.GetLine();
      IO.Put("Bitte geben sie den CD-Titel an:     ");
      neueCD.titel:= IO.GetLine();
      IO.Put("Bitte geben sie das CD-Label an:     ");
      neueCD.label:= IO.GetLine();
      IO.Put("Bitte geben sie die Seriennummer an: ");
      neueCD.srnr:= IO.GetLine();
      (* Versuch die Datei erneut zu oeffnen und Datensatz zu schreiben. *)
      (* Abbruch bei Fehler.                                             *)
      LOOP
       TRY
        Channel:= FileWr.OpenAppend(Pfad);
        Wr.PutText(Channel,Text.Cat(neueCD.interpret,Text.Cat(";",Text.Cat(neueCD.titel,Text.Cat(";",Text.Cat(neueCD.label,Text.Cat(";",Text.Cat(neueCD.srnr,"\n"))))))));
        Wr.Close(Channel);
        EXIT;
       EXCEPT
        | Wr.Failure => IO.Put("\nSchreibfehler! Wiederholen [j/n]");
          Wahl:= IO.GetChar();EVAL IO.GetLine();
          IF Wahl#'J' AND Wahl#'j' THEN EXIT; END;
        | OSError.E => IO.Put("\nSchreibfehler! Wiederholen [j/n]");
          Wahl:= IO.GetChar();EVAL IO.GetLine();
          IF Wahl#'J' AND Wahl#'j' THEN EXIT; END;
        | Thread.Alerted => IO.Put("\nSchreibfehler! Wiederholen [j/n]");
          Wahl:= IO.GetChar();EVAL IO.GetLine();
          IF Wahl#'J' AND Wahl#'j' THEN EXIT; END;
       END;
      END;
      Wahl:= '2';
    | '2' =>
      (* Versuch die Datei erneut zu oeffnen und Datensatz zu lesen. *)
      TRY
      RdChannel:= FileRd.Open(Pfad);
        (* Bei Erfolg, lies bis Dateiende erreicht einen Datensatz ein... *)
        WHILE NOT Rd.EOF(RdChannel) DO
          Line:= Rd.GetLine(RdChannel);
          (* ...und weise dessen Daten Einzelelementen zu, *)
          FOR j:=1 TO 4 DO
            (* dazu Suche naechstes Semikolon, wenn gefunden,    *)
            (* weise Datensatz zu, fahre mit Restdatensatz fort. *)
            IF j>1 THEN
              Von:= Bis+1;
              Line:= Text.Sub(Line,Von);
            END;
            IF j<4 THEN
              Bis:= Text.FindChar(Line,';');
            END;
            CASE j OF
             | 1 => neueCD.interpret:= Text.Sub(Line,0,Bis);
             | 2 => neueCD.titel:= Text.Sub(Line,0,Bis);
             | 3 => neueCD.label:= Text.Sub(Line,0,Bis);
             | 4 => neueCD.srnr:= Text.Sub(Line,0,Text.Length(Line));
            ELSE 
            END;
          END;
          (* Ausgabe des Datensatzes *)
          IO.Put("\nInterpret:    "); IO.Put(neueCD.interpret);
          IO.Put("\nCD-Titel:     "); IO.Put(neueCD.titel);
          IO.Put("\nCD-Label:     "); IO.Put(neueCD.label);
          IO.Put("\nSeriennummer: "); IO.Put(neueCD.srnr);
          IO.Put("\n");
        END;
       EXCEPT
       (* Bei Fehler, Abbruch. *)
        | Rd.EndOfFile =>
        | Rd.Failure => IO.Put("Lesefehler!\n");
        | Thread.Alerted => IO.Put("Lesefehler!\n");
        | OSError.E => IO.Put("Lesefehler!\n");
       END;
      TRY Rd.Close(RdChannel);
      EXCEPT
       | Rd.Failure =>
       | Thread.Alerted =>
      END;
    | '3' =>
      (* Datei leer oeffnen, und die leere Datei speichern. *)
      TRY
          Channel:= FileWr.Open(Pfad);Wr.Close(Channel);
        EXCEPT
        (* Bei Fehler, Abbruch. *)
         | Wr.Failure => IO.Put("\nSchreibfehler!");
         | OSError.E => IO.Put("\nSchreibfehler!");
         | Thread.Alerted => IO.Put("\nSchreibfehler!");
      END;
    ELSE
    END;
  END;

END CD.

Testlauf:

Bitte geben sie den Namen der Zieldatei an:
neu.txt

[1] Eingabe eines neuen Datensatzes
[2] Anzeigen des CD-Bestandes
[3] Loeschen aller Datensaetze
[4] Beenden des Programms
1

Bitte geben sie den Interpreten an:  abcd
Bitte geben sie den CD-Titel an:     efgh
Bitte geben sie das CD-Label an:     ijkl
Bitte geben sie die Seriennummer an: 123 456-7

[1] Eingabe eines neuen Datensatzes
[2] Anzeigen des CD-Bestandes
[3] Loeschen aller Datensaetze
[4] Beenden des Programms
1

Bitte geben sie den Interpreten an:  mn
Bitte geben sie den CD-Titel an:     opq
Bitte geben sie das CD-Label an:     rstu
Bitte geben sie die Seriennummer an: 890 abc-0

[1] Eingabe eines neuen Datensatzes
[2] Anzeigen des CD-Bestandes
[3] Loeschen aller Datensaetze
[4] Beenden des Programms
1

Bitte geben sie den Interpreten an:  0v
Bitte geben sie den CD-Titel an:     1w
Bitte geben sie das CD-Label an:     2qr
Bitte geben sie die Seriennummer an: x01 y02z03_0

[1] Eingabe eines neuen Datensatzes
[2] Anzeigen des CD-Bestandes
[3] Loeschen aller Datensaetze
[4] Beenden des Programms
2

Interpret:    abcd
CD-Titel:     efgh
CD-Label:     ijkl
Seriennummer: 123 456-7

Interpret:    mn
CD-Titel:     opq
CD-Label:     rstu
Seriennummer: 890 abc-0

Interpret:    0v
CD-Titel:     1w
CD-Label:     2qr
Seriennummer: x01 y02z03_0

[1] Eingabe eines neuen Datensatzes
[2] Anzeigen des CD-Bestandes
[3] Loeschen aller Datensaetze
[4] Beenden des Programms
4

Bitte geben sie den Namen der Zieldatei an:
neu.txt

[1] Eingabe eines neuen Datensatzes
[2] Anzeigen des CD-Bestandes
[3] Loeschen aller Datensaetze
[4] Beenden des Programms
1

Bitte geben sie den Interpreten an:  1234
Bitte geben sie den CD-Titel an:     123
Bitte geben sie das CD-Label an:     12
Bitte geben sie die Seriennummer an: 1

[1] Eingabe eines neuen Datensatzes
[2] Anzeigen des CD-Bestandes
[3] Loeschen aller Datensaetze
[4] Beenden des Programms
1

Bitte geben sie den Interpreten an:  5
Bitte geben sie den CD-Titel an:     78
Bitte geben sie das CD-Label an:     789
Bitte geben sie die Seriennummer an: 65890

[1] Eingabe eines neuen Datensatzes
[2] Anzeigen des CD-Bestandes
[3] Loeschen aller Datensaetze
[4] Beenden des Programms
1

Bitte geben sie den Interpreten an:  a
Bitte geben sie den CD-Titel an:     b
Bitte geben sie das CD-Label an:     c
Bitte geben sie die Seriennummer an: d

[1] Eingabe eines neuen Datensatzes
[2] Anzeigen des CD-Bestandes
[3] Loeschen aller Datensaetze
[4] Beenden des Programms
2

Interpret:    abcd
CD-Titel:     efgh
CD-Label:     ijkl
Seriennummer: 123 456-7

Interpret:    mn
CD-Titel:     opq
CD-Label:     rstu
Seriennummer: 890 abc-0

Interpret:    0v
CD-Titel:     1w
CD-Label:     2qr
Seriennummer: x01 y02z03_0

Interpret:    1234
CD-Titel:     123
CD-Label:     12
Seriennummer: 1

Interpret:    5
CD-Titel:     78
CD-Label:     789
Seriennummer: 65890

Interpret:    a
CD-Titel:     b
CD-Label:     c
Seriennummer: d

[1] Eingabe eines neuen Datensatzes
[2] Anzeigen des CD-Bestandes
[3] Loeschen aller Datensaetze
[4] Beenden des Programms
4

Bitte geben sie den Namen der Zieldatei an:
neu.txt

[1] Eingabe eines neuen Datensatzes
[2] Anzeigen des CD-Bestandes
[3] Loeschen aller Datensaetze
[4] Beenden des Programms
2

Interpret:    abcd
CD-Titel:     efgh
CD-Label:     ijkl
Seriennummer: 123 456-7

[...]

[1] Eingabe eines neuen Datensatzes
[2] Anzeigen des CD-Bestandes
[3] Loeschen aller Datensaetze
[4] Beenden des Programms
3

[1] Eingabe eines neuen Datensatzes
[2] Anzeigen des CD-Bestandes
[3] Loeschen aller Datensaetze
[4] Beenden des Programms
2

[1] Eingabe eines neuen Datensatzes
[2] Anzeigen des CD-Bestandes
[3] Loeschen aller Datensaetze
[4] Beenden des Programms
4

Testlaufende.