Die Dateiverwaltung für den C64 und C128
Die Dateiverwaltung für den C64 und C128 | |||
---|---|---|---|
Sprache | deutsch | ||
Autor(en) | Said Baloui | ||
Verlag | Data Becker | ||
Jahr | 1986 | ||
ISBN | ISBN 3-89011-103-3 | ||
Neupreis | DM | ||
Datenträger | Diskette zum Buch erhältlich | ||
Seitenzahl | 272 | ||
letzte Auflage | |||
Genre | Programmieren | ||
Information |
Buchrückseite[Bearbeiten | Quelltext bearbeiten]
DAS STEHT DRIN:
Dateiverwaltung selbstgemacht! Dieses Buch enthält eine professionelle Dateiverwaltung zum Abtippen. Alle Routinen des Programmes werden ausführlich, von Struktogrammen unterstützt, erklärt. Das Dateiverwaltungsprogramm kann problemlos an Ihre eigenen Bedürfnisse angepaßt werden; die einzelnen Routinen lassen sich für andere Programme ausgezeichnet verwenden.
Aus dem Inhalt:
- Ausführliche Diskussion der verwendeten Datenstrukturen
- Die Eingabemaske
- Verschiedene Eingaberoutinen
- Eintragen, Suchen, Sortieren und Löschen von Datensätzen
- Druckeranpassung durch Druckparameter
- Individuelle Änderungen
- Zur Interpretation von Struktogrammen
- Alle Routinen auch für den C-128
UND GESCHRIEBEN HAT DIESES BUCH:
Said Baloui ist Student und Programmierer professioneller Dateiverwaltungsprogramme. Er gehört seit langer Zeit zum Team der DATA BECKER Autoren.
Inhaltsverzeichnis[Bearbeiten | Quelltext bearbeiten]
0. Einleitung ........................................... 11 1. Anforderungen an das Programm ........................ 15 2. Datenstrukturen ...................................... 19 3. Unterroutinen ........................................ 29 3.1 Cursor setzen ....................................... 29 3.2 Verbesserte Input#-Routine .......................... 30 3.3 Suchroutine ......................................... 33 3.4 Routine zum Löschen/Einfügen ........................ 44 3.5 Verbesserte Eingaberoutine .......................... 53 3.6 Die Eingabemaske .................................... 64 3.7 Fehlerkanal lesen/ausgeben .......................... 75 3.8 Positionieren ....................................... 77 4. Das Hauptprogramm .................................... 81 4.1 Ablaufschema des Hauptprogramms ..................... 81 4.2 Initialisierung ..................................... 86 4.3 Infodateien einlesen/Datei erstellen ................ 94 4.4 Das Hauptmenü ....................................... 101 4.5 Eintragen von Datensätzen ........................... 103 4.6 Suchen von Datensätzen .............................. 115 4.7 Rückkehr zu Menü 1, Weitersuchen, neue Suche ........ 130 4.8 Menü 2 .............................................. 130 4.9 Alphabetisch nächster Datensatz ..................... 138 4.10 Alphabetisch vorhergehender Datensatz .............. 140 4.11 Löschen eines Datensatzes .......................... 142 4.12 Ändern eines Datensatzes ........................... 146 4.13 Ausdruck des aktuellen Datensatzes ................. 150 4.14 Druckparameter ..................................... 153 4.15 Geordnete Ausgabe der Datei ........................ 157 4.16 Reorganisation ..................................... 170 5. Allgemeine Erläuterungen ............................. 181 5.1 Individuelle Änderungen ............................. 181 5.2 Anleitung zur Programmbenutzung ..................... 186 5.3 Eingeben des Programms/Übernahme einzelner Routinen ............................................ 197 5.4 Zur Interpretation von Struktogrammen ............... 200 6. Anpassung an den C-128 ............................... 213 6.1 Anpassung der Assemblerroutinen ..................... 213 6.2 Anpassung des BASIC-Teils ........................... 217 6.3 Änderungen der Programmbedienung .................... 220 6.4 Assemblerroutinen in eigenen Programmen ............. 220 7. Vollständige Programmlistings ........................ 223 7.1 Vollständiges Listing der C-64-Version .............. 223 7.2 Vollständiges Listing der C-128-Version ............. 246
Leseprobe[Bearbeiten | Quelltext bearbeiten]
(1. Auflage - Seite 19ff: Kapitel "2. Datenstrukturen")
Dieses Kapitel ist zum Verständnis der vorgestellten Dateiverwaltung unumgänglich. Es beschreibt den grundsätzlichen Aufbau des Gesamtprogramms, die verwendeten Datenstrukturen und den prinzipiellen Ablauf so grundlegender Programmteile wie "Eintragen", "Suchen nach", "Löschen" und "Ändern von Datensätzen".
Grundlage einer jeden Dateiverwaltung sind die verwendeten Datenstrukturen. Welche Datenstrukturen zur Anwendung kommen, hängt von den gestellten Anforderungen ab. Diese Anforderungen wurden im vorigen Kapitel erläutert. Es ergab die Notwendigkeit einer index-sequentiellen Datei, bei der die Index-Datei (alphabetisch) geordnet ist.
Zum besseren Verständnis sehen Sie auf der nächsten Seite eine index-sequentielle Datei schematisch dargestellt. In der Datensatzdatei befinden sich die kompletten Datensätze. In diesem Beispiel besteht ein Datensatz aus den Feldern "Name", "Straße" und "Ort".
Die Datensatzdatei befindet sich nur auf der Diskette, nicht im Rechnerspeicher. Wegen der meist geringen Kapazität von Rechnerspeichern ist dies bei großen Dateien auch gar nicht möglich.
Das Feld "Name" ist der Index oder Schlüssel. Die kleine IndexDatei, die zu jedem Datensatz der Datei den jeweiligen Namen der gesamten Adresse enthält, wird komplett im Rechnerspeicher gehalten.
Zu jedem Namen, d.h. zu jedem Eintrag in dieser Index-Datei, gehört ein sog. "Zeiger" oder auch "Pointer". Dieser Zeiger ist eine Zahl, die Auskunft darüber gibt, wo auf der Diskette der komplette Datensatz zu finden ist.
Schema einer index-sequentiellen Datei: Datensatzdatei:
Satz- bzw. Recordnummer |
Name | Ort | Straße |
---|---|---|---|
1 | Maier | München | Gerlosweg 5 |
2 | Jakob | Dortmund | Aalweg 13 |
3 | Lothar | Heidelberg | Sternstr. 1 |
4 | Müller | Köln | Iffezweg 3 |
Index-Datei:
Name | Zeiger auf Recordnr. |
---|---|
Jakob | 2 |
Lothar | 3 |
Maier | 1 |
Müller | 4 |
Die komplett im Speicher gehaltene Index-Datei muß sich selbstverständlich auch auf der Diskette befinden. Im vorgestellten Programm wird sie als sequentielles File auf der Diskette abgespeichert.
Beim Starten des Programms wird dieses sequentielle File in den Rechnerspeicher geladen und beim Beenden der Arbeit mit dem Programm wird es wieder komplett abgespeichert, wenn in der Zwischenzeit Anderungen der Index-Datei aufgetreten sein sollten (Eintragen, Löschen, Ändern von Datensätzen). Für die eigentliche Datensatzdatei verwenden wir eine relative Datei, in der unter Angabe der Record-Nummer direkt auf einen bestimmten Datensatz zugegriffen werden kann.
Nun wird auch die Bedeutung des Zeigers (Pointers) ersichtlich: er stellt - über die Recordnummer - die Verbindung zwischen Indexeintrag und zugehörigem Datensatz her:
Wird die Adresse von Herrn "Lothar" gesucht, so durchsucht das Programm die Tabelle der Indexeinträge im Speicher und findet den passenden Eintrag "Lothar" (3. Eintrag in der Index-Datei). Der zugehörige 3. Zeiger der Pointertabelle weist auf Record Nr. 3.
Damit steht fest, daß die zu dem Namen "Lothar" gehörende komplette Adresse in Record Nr. 3 steht. Auf diesen wird nun direkt in der relativen Datei zugegriffen, er wird eingelesen und kann anschließend auf Bildschirm oder Drucker ausgegeben werden.
Soviel zur Theorie. Es stellt sich nun die Frage, wie eine solche index-sequentielle Datei praktisch verwirklicht wird. Das eigentliche Problem stellt die geordnete Index-Datei dar. Für sie werden zwei Tabellen benötigt, die in Form sog. "Felder" oder "Arrays" realisiert werden.
Und zwar ein Stringarray, in dem die Indexeinträge, z.B. die einzelnen Namen, abgelegt werden und ein Integerarray, in dem die zugehörigen Zeiger (= Recordnummer) abgelegt werden. Im Programm werden für diese beiden Felder folgende Bezeichnungen verwendet:
jf$(ı), jf$(2), jf$3), ..., Jf$(n) = Stringarray mit den Indexeinträgen
p%(1), P%(2), P%(3), ..., p%(n) = Integerarray mit den zugehörigen Pointern. (= Recordnummern)
Zum Abspeichern eines Datensatzes werden die einzelnen Datensatzfelder zu einem einzigen String zusammengebaut und durch Carriage Return ("chr$(13)", jenes Zeichen, das durch Drücken der Taste "return" erzeugt wird) voneinander getrennt.
Im folgenden wird für Carriage Return die Abkürzung "cr" verwendet.
Dieser String, der nun den kompletten Datensatz enthält, wird unter Angabe einer Recordnummer in die Datensatzdatei geschrieben. Die Index-Datei befindet sich ebenfalls - als sequentielles File - auf der Diskette, wird jedoch bei der Arbeit mit dem Programm in den vorbereiteten Arrays im Speicher gehalten.
Die Beispieldatei aus dem Schema würde daher folgendermaßen realisiert:
Diskette:
(relative) Datensatzdatei:
Record Nr. 1: Maier cr München cr Gerlosweg 5 Record Nr. 2: Jakob cr Dortmund cr Aalweg 13 Record Nr. 3: Lothar cr Heidelberg cr Sternstr. ] Record Nr. 4: Müller cr Köln cr Iffezweg 3
(sequentielle) Index-Datei:
Jakob cr 2 cr Lothar cr 3 cr Maier cr I cr Müller cr 4 cr
Speicher (nur Index-Datei):
Index-Datei:
jf$(1) = "Jakob" p%(l) = 2 jf$(2) = "Lothar" p%(2) = 3 jf$(3) = "Maier" p%(3) = 1 jf$(4) = "Müller" p%(4) = 4
Beispiel: Die Adresse von Herrn "Lothar" wird gesucht. Das Arrayfeld "jf$(..)" wird im Speicher nach dem Namen "Lothar" durchsucht. Das gesuchte Element besitzt den Index "2". Der zugehörige Zeiger ist demnach der Zeiger mit dem gleichen Index "2", also "p%(2)". Da gilt:
p%(2)=3
ist der gesuchte Datensatz im Record Nr. 3. Dieser Record und damit die gesuchte Adresse von "Lothar" wird nun aus der Datensatzdatei von Diskette eingelesen.
Die praktische Realisierung der Suche in unserer index-sequentiellen Datei dürfte nun einigermaßen geklärt sein.
Vorläufig noch ungeklärt ist der prinzipielle Ablauf beim Eintragen, Löschen und Andern von Datensätzen.
Eintragen von Datensätzen
Wir wollen in unsere Datei den Datensatz: "Kunz, Otterweg 4, Mühlheim" eintragen. Zuerst wird der komplette Datensatz in die Datensatzdatei eingetragen. Er wird an das Ende der Datensatzdatei geschrieben, d.h. in Record Nr. 5.
Problematischer ist der Eintrag des Namens "Kunz" in die Index-Datei, da ja deren alphabetische Ordnung erhalten bleiben muß. "Kunz" darf keinesfalls einfach an das Ende der IndexTabelle "angehängt" werden, er muß gemäß der alphabetischen Ordnung hinter "Jakob" und vor "Lothar" stehen, also den Index "2" erhalten (jf$(2) = "Kunz").
Damit "Lothar" nicht überschrieben wird, muß in der IndexDatei Platz geschaffen werden; alle Einträge ab Index Nr. 2 müssen verschoben werden. Ebenso sind selbstverständlich die zugehörigen Zeiger zu verschieben:
jf$(1) = "Jakob" p%(1l) = 2 .................................. (freigewordener Platz) jf$(3) = "Lothar" p%(3) = 3 jf$(4) = "Maier" p%(4) = 1 jf$(5) = "Müller" p%(5) = 4
Nun kann "Kunz" an der richtigen Stelle mit dem Index "2" eingefügt werden. Da der zugehörige Datensatz in Record Nr. 5 abgespeichert wurde, erhält der zu "Kunz" gehörende Zeiger den Wert "5":
jf$(1) = "Jakob" p%(1) = 2 jf$(2) = "Kunz" p%(2) = 5 jf$(3) = "Lothar" p%(3) = 3 jf$(4) = "Maier" p%(4) = 1 jf$(5) = "Müller" p%(5) = 4
Löschen von Datensätzen
Um nun z.B. Herrn "Lothar" zu löschen, muß zuerst der Record, in dem sich der zugehörige Datensatz befindet, freigegeben und als nicht mehr belegt gekennzeichnet werden. Ein Record wird als nicht belegt gekennzeichnet, indem er mit dem Zeichen "pi" ("chr$(255)") beschrieben wird.
Komplizierter ist wiederum das Löschen des Indexeintrages. Man könnte die Variablen "jf$(3)" und "p%(3)" ebenfalls durch ein Sonderzeichen als frei kennzeichnen. Da unser knapper Rechnerspeicherplatz eine solche Verschwendung von Speicherplatz jedoch verbietet, besteht die elegantere Methode darin, alle nachfolgenden Indexeinträge aufzurücken:
jf$(1) = "Jakob" p%(l) = 2 jf$(2) = "Kunz" p%(2) = 5 jf$(3) = "Maier" p%(3) = 1 jf$(4) = "Müller" p%(4) = 4
Ändern von Datensätzen
Das Ändern von Datensätzen ist unproblematisch: Zuerst wird der alte Datensatz gelöscht, anschließend der neue - geänderte Datensatz eingetragen. Hierzu können die bereits vorhandenen Routinen zum Löschen und Eintragen verwendet werden.
Beispiel: Herr "Maier" ist umgezogen. Seine neue Adresse ist: "Maier, Karlsruhe, Wienandstr. 3b". Wir verwenden die Daten aus unserem ursprünglichen Schema ohne Berücksichtigung der zwischenzeitlich erfolgten Anderungen:
Zuerst wird "Maier", München, Gerlosweg 5" gelöscht:
Datensatzdatei:
Record Nr. 1: chr$(255) (Freigabezeichen) Record Nr. 2: Jakob cr Dortmund cr Aalweg 13 Record Nr. 3: Lothar cr Heidelberg cr Sternstr. 1 Record Nr. 4: Müller cr Köln cr Iffezweg 3
Index-Datei:
jf$(1) = "Jakob" p%(l) = 2 jf$(2) = "Lothar" p%(2) = 3 j£$(3) = "Müller" p%(3) = 4
Nun wird "Maier, Karlsruhe, Wienandstr. 3" eingetragen:
Datensatzdatei:
Record Nr. 1: chr$(255) (Freigabezeichen) Record Nr. 2: Jakob cr Dortmund cr Aalweg 13 Record Nr. 3: Lothar cr Heidelberg cr Sternstr. 1 Record Nr. 4: Müller cr Köln cr Iffezweg 3 Record Nr. 5: Maier cr Karlsruhe cr Wienandstr. 3
Index-Datei:
jf$(1) = "Jakob" p%(1) = 2 jf$(2) = "Lothar" p%(2) = 3 jf$(3) = "Maier" p%(3) = 5 jf$(4) = "Müller" p%(4) = 4
Wie Sie sehen, wird der freigegebene Record Nr. 1 beim Eintragen eines neuen Datensatzes nicht berücksichtigt. Ein neuer Datensatz wird an das Ende der Datei angefügt.
Bei einer großen Datei, in der sehr häufig Lösch- bzw. Anderungsvorgänge stattfinden, entstehen aufgrund dieser Arbeitsweise Lücken in der Datensatzdatei. Speziell aus diesem Grund finden Sie in der vorgestellten Dateiverwaltung die Funktion "Reorganisation", die das "Zusammenziehen" der Datensatzdatei und damit das Auffüllen dieser Lücken ermöglicht.
Zusammenfassung
Die grundsätzliche Datenstruktur unseres Programms ist also die einer index-sequentiellen Datei mit geordneter Index-Datei und ungeordneter Datensatzdatei. Die Verbindung zwischen IndexDatei und Datensatzdatei wird über Zeiger hergestellt. Zu jedem Indexeintrag gehört ein Zeiger, der den Record angibt, in dem sich der zugehörige komplette Datensatz befindet. Zur Realisierung der Index-Datei wird ein Stringarray für die Indexeinträge und ein Integerarray für die zugehörigen Pointer verwendet.
Bei der Suche über den Index wird die im Speicher gehaltene Index-Datei durchsucht und über die Zeiger auf die zugehörigen Datensätze zugegriffen. Wird nicht über den Index gesucht, muß die Datensatzdatei sequentiell abgesucht werden, d.h. Datensatz für Datensatz wird eingelesen, bis der gesuchte gefunden wurde.
Bei allen "Änderungsvorgängen" (Eintragen, Löschen, Ändern) muß beachtet werden, daß neue Datensätze an das Ende der Datensatzdatei angehängt werden, beim Löschen Lücken in der Datensatzdatei entstehen, und vor allem, daß die Ordnung der Index-Datei immer erhalten bleiben muß!
Auf einen äußerst wichtigen Punkt bei der Bedienung des Programms, der sich zwangsläufig aus den verwendeten Datenstrukturen ergibt, möchte ich noch hinweisen:
Bei Änderungsvorgängen wird die Datensatzdatei auf der Diskette sofort berichtigt; die Index-Datei wird jedoch nur im Speicher entsprechend korrigiert, nicht auf der Diskette. Dies muß beim Beenden der Arbeit mit dem Programm geschehen:
Das sequentielle File, das die Index-Datei enthält, wird nach Änderungen durch die neue, aktualisierte Index-Datei, die sich im Speicher befindet, komplett überschrieben. Das Programm darf daher niemals durch Ausschalten des Rechners beendet werden!
Es ist unbedingt notwendig, zum Beenden der Arbeit mit dem Programm die vorgesehene Funktion im Auswahlmenü anzuwählen, da sich sonst beim neuen Starten des Programms nur die alte, nicht aktualisierte Version der Index-Datei auf der Diskette befindet.
Da jedoch immer mit der Möglichkeit eines Stromausfalls oder anderen Ursachen gerechnet werden muß, die verhindern, daß eine geänderte Index-Datei ordnungsgemäß abgespeichert wird, werden wir einen speziell für diesen Fall gedachten Programmteil "Reorganisation" vorstellen, der in der Lage ist, aus der Datensatzdatei eine vollständig aktualisierte Index-Datei zu erstellen.
Nachdem nun geklärt wurde, welche Datenstrukturen im Programm verwendet werden, kann die eigentliche Programmbeschreibung beginnen. In den folgenden Kapiteln werden Routinen erläutert, die im weiteren ständig im Programm Verwendung finden.