Claus Schönleber

Hitchhacker´s Guide To PASCAL  [Vol. 1]

 [ zurück | weiter ]
   [ Start | Beispielprogramme Download | Home ]

Inhalt

Compiler
Programmieren
Datentypen,
Variablen,
Standardfunktionen
Logik
Verzweigung,
Strukturierung
Schleifen
Felder (Arrays)
Verteiler: CASE
Zeichenketten
(Strings)
Textdateien
Module
(Prozeduren,
Funktionen)
Anhang
(Operatoren,
abgeleitete
Funktionen)
 
 
 

 

 

Strings

Der Typ STRING ist zwar schon angesprochen worden; er beinhaltet aber eine Menge von Eigenschaften und soll deswegen an dieser Stelle gesondert betrachtet werden. 

Zunächst die Einbindung des Typs STRING in die Typen von PASCAL. Was ein String ist und wie er im Adressraum der Maschine grundsätzlich abgelegt wird, ist schon besprochen worden. Allerdings fehlt noch die Verbindung zu PASCAL. Im ursprünglichen Standard von Nikolaus Wirth wurde der Name "string" zwar schon eingeführt, da auch zu diesem Zeitpunkt schon klar war, daß man ohne diesen Typ nicht auskommt; er belegte aber keine eigene Typdefinition. Ein String wurde definiert als: 

"Sequences of characters enclosed by quote marks...", 

also Zeichenfolgen in Hochkommata. Zurückgeführt wurde diese Konstruktion auf eine spezielle Form eines Feldes, nämlich das PACKED ARRAY. Der Zusatz PACKED bedeutet einfach, daß die Elemente am Ende eines Feldes, die nicht gebraucht werden, im Adressraum der Maschine auch keinen Platz belegen. Ist zum Beispiel ein Feld mit 10 Elementen vordefiniert, wobei nur die ersten 3 Felder belegt sind, bedeutet dies, daß die restlichen 7 unbenutzten Feldelemente im Adressraum der Maschine auch nicht eingerichtet werden. Man spart dadurch natürlich Platz. Dementsprechend war der Typ String definiert als: 

TYPE string = PACKED ARRAY [1..n] OF char;
wobei n die festzulegende, maximale Länge eines Strings darstellt. Um einen String auf den Bildschirm zu bringen, braucht man dann die Hilfe einer Schleife. Irgendwo steht dann die Anzahl der tatsächlich belegten Feldelemente, nennen wir sie x: 
FOR i := 1 TO x DO 
  write (s [i]); 
writeln; 
Der Sondertyp des "gepackten" Feldes spielte bei Microcomputern keine Rolle mehr, da man wegen der geringen Speicherkapazität älterer Modelle sowieso automatisch "packte", also komprimierte, wo dies möglich war. So ist das Wort PACKED zwar in allen Compilern noch zugelassen, hat aber meist keine Wirkung mehr. In TurboPASCAL wird immer "gepackt". 

Der Typ STRING ist in TurboPASCAL so definiert: 

TYPE string = ARRAY [0..n] OF char;
Dabei steht im Element 0 die aktuelle Länge des Strings. Das Wort STRING ist, im Gegensatz zu allen anderen Typnamen, ein reserviertes Wort und wird deshalb in diesem Kurs, soweit es den Typnamen betrifft, durchgehend groß geschrieben. 

Der Typ STRING 

Eine Variable vom Typ STRING wird folgendermaßen definiert: 
VAR <variable>{,<variable>} : STRING [<länge>]; 
Beispiel: 
VAR name : STRING [30]; 
Man kann der Form der Deklaration die Herkunft vom Array noch gut ansehen. In der eckigen Klammer hinter dem Wort STRING ist die maximale Länge des Strings angegeben. 

TurboPASCAL: Die maximale Länge darf 255 nicht überschreiten. Ab Version 5.0: Läßt man die Längenangabe weg, wird die Länge auf 255 festgesetzt. 

Da der Typ STRING eigentlich ein Array ist, kann man auf die einzelnen Zeichen aus dem String wie bei einem Array zugreifen. Es ist zwar nicht die feine Wirth'sche Art, aber es ist oft handlicher, als die Stringfunktionen zu benutzen, die dasselbe machen, aber wesentlich
längere Ausdrücke ergeben. Angenommen, die Variable aus dem gerade besprochenen Beispiel hätte einen Inhalt: 

name := 'Donaudampfschiff'; 
Wollen wir nun einen Buchstaben (also ein Feldelement) herauspicken, sagen wir das zweite "a" (7. Buchstabe), dann kann man das so formulieren (in einer Zuweisung an eine Variable "c" vom Typ char): 
c := name [7]; 
Achten Sie aber darauf, daß es unter Umständen Compiler gibt, die das nicht zulassen! In TurboPASCAL geht es jedenfalls. 

Eine andere Besonderheit bei dieser Methode tritt bei der Benutzung eines Stringfeldes auf. Auch der Typ STRING läßt die Benutzung eines Feldes zu. Vergleichen wir zwei Felder, ein "eindimensionales" STRING-Feld und ein zweidimensionales char-Feld (In Wahrheit sind natürlich beide zweidimensional!). Die Kommentarzeilen enthalten den Hinweis auf die Funktion und Reihenfolge der Dimensionen. 

Beispiel: 

VAR seite1 : ARRAY [1..25] OF STRING [80]; (*** zeilen, spalten ***) 
    seite2 : ARRAY [1..80,1..25] OF char;  (*** spalten,zeilen ***) 
Wie wird nun ein Feldelement aus den entsprechenden Feldern selektiert? Betrachten wir die Koordinaten 50. Spalte und 17. Zeile : 
write (seite1 [17] [50]); 
write (seite2 [50,17]); 
Die Reihenfolge beim Feld "seite2" ist deswegen so gewählt, weil sie der üblichen Reihenfolge von Koordinaten entspricht (zuerst horizontale, dann vertikale Position). Sie kann bei Bedarf und Geschmack leicht ausgetauscht werden. 

Wichtig bei der Selektion des Feldelements ist die Tatsache, daß das Feld "seite1" getrennte Koordinatenangaben besitzt, da das Feld formal nur eindimensional ist. Um in dem String (Feldelement) "seite1 [17]" den 50. Buchstaben zu selektieren, muß das formal durch die angehängten Feldklammern ausgedrückt werden. 

Solche STRING-Felder sind bequem bei der Bearbeitung von Texten auf dem Bildschirm; es sind allerdings die Schwierigkeiten zu beachten bei der Benutzung. 

Wer für "saubere" Programmierung ist, sollte bei Bedarf dann auf die entsprechenden (und im nächsten Abschnitt besprochene) Standardtextfunktion "copy" zurückgreifen, wo vorhanden. 

Es gibt auch einen Operator für diesen Typ: Die "Addition" von Strings, auch Konkatenation genannt. Damit werden verschiedene Strings hintereinander gehängt und zu einem String verschmolzen: 

Beispiel: 

'Hans' + ' ' + 'Dampf' 
ergibt den String 
'Hans Dampf'. 

Standardtextfunktionen und -prozeduren (TurboPASCAL) 

Abweichend von der bisherigen Tendenz sollen jetzt einige notwendige Funktionen und Prozeduren besprochen werden, die im Wirth'schen Standard fehlen, da sie mehr oder weniger leicht nachträglich einzubauen sind. Bequemerweise sind sie in den meisten Dialekten, so zum Beispiel in TurboPASCAL, schon implementiert. 

Zunächst die Funktionen (Zuweisung in den Beispielen erfolgt an eine STRING-Variable "resultat" bzw. an eine integer- Variable "x"): 


Zusammensetzen von Strings: concat 

Allgemeine Form: concat (<string>,<string>{,<string>}) 

Erläuterung: Es können beliebig viele Strings konkateniert werden. Sie werden in der Reihenfolge ihres Auftretens zusammengesetzt. 

Eingabetyp/Ausgabetyp: STRING/STRING 

Beispiele: 

resultat := concat ('Dampf','schiff') 
ergibt: 'Dampfschiff' 
 
writeln (concat ('A','B','C'); 
ergibt: 'ABC' 

Extraktion einer Zeichenkette aus einer anderen: copy 

Allgemeine Form: copy (<string>,<position>,<länge>); 

Erläuterung: In <position> gibt ein integer-Ausdruck die Anfangsposition des zu extrahierenden Strings an, in <länge> steht die Anzahl der Zeichen, die ab <position> extrahiert werden sollen. 

Eingabetyp/Ausgabetyp: STRING/STRING 

Beispiele: 

resultat := copy ('Knochen',2,4); 
ergibt: 'noch' 
 
writeln (copy ('Ensamble',2,3)); 
ergibt: 'nsa' 


Achtung: Wenn man versucht, mit Hilfe von copy ein Zeichen aus einem String zu extrahieren, bekommt man einen String der Länge 1, nicht eine char-Konstante! Diese beiden Typen sind nicht zuweisungskompatibel. 


Berechnung der Stringlänge: length 

Allgemeine Form: length (<string>) 

Erläuterung:Zählt die Zeichen eines Strings und weist die errechnete Zahl einer integer- Variablen zu. 

Eingabetyp/Ausgabetyp: STRING/integer 

Beispiele: 

resultat := 'Donaudampfschiff'; 
x := length (resultat); 
ergibt: integer-Wert 16 in "x" 
 
writeln (length (resultat)); 
ergibt: 16 auf dem Bildschirm 

Suche nach String in einem anderen String: pos 

Allgemeine Form: pos (<string1>,<string2>) 

Erläuterung: sucht <string1> in <string2>. Bei Erfolg wird die Position des ersten Buchstabens von <string1> in <string2> als integer-Wert angegeben, bei Mißerfolg wird eine 0 zurückgegeben. 

Eingabetyp/Ausgabetyp: STRING/integer 

Beispiele:

x := pos ('ist','Jurist'); 
ergibt: 4 in "x" 
 
x := pos ('wissen','Jurist'); 
ergibt: 0 in "x" 
 
writeln (pos ('lala','Oghelala')); 
ergibt: 5 in "x" 



Bleiben noch die Prozeduren: 


Löschen eines Strings in einem anderen: delete 

Allgemeine Form: delete (<string>,<position>,<länge>);

Erläuterung: Löscht eine Zeichenkette ab <position> der Länge <länge> aus <string>. <position> und <länge> sind integer-Ausdrücke, <string> ist vom Typ STRING. Ist <position> größer als die Gesamtlänge von <string>, wird nichts gelöscht; überschreitet <länge> + <position> die Gesamtlänge von <string>, werden nur die innerhalb von <string> liegenden Zeichen gelöscht. Ist <position> größer als 255 oder kleiner als 0, wird eine Laufzeitfehlermeldung ausgegeben. Das Ergebnis steht in <string>. 

Beispiele: 

delete ('Sparschwein',8,1) 
ergibt: 'Sparschein' 
 
delete ('Programmierer',9,5); 
ergibt: 'Programm' 

Einfügen eines Strings in einen anderen: insert 

Allgemeine Form: insert (<string>,<string>,<position>);

Erläuterung: Fügt den ersten <string> in den zweiten <string> an der Stelle <position> ein. Die <string>s sind vom Typ STRING, <position> ist ein integer-Ausdruck. Ist <position> größer als die Länge des zweiten <strings>, so wird der erste an den zweiten angehängt. überschreitet das Ergebnis die definierte Maximallänge des Zielstrings, so wird am Ende entsprechend abgeschnitten. Ist <position> größer als 255 oderkleiner als 0, erfolgt eine Laufzeitfehlermeldung. Das Ergebnis steht im ersten <string>. 

Beispiele: 

resultat := 'Donauschiff'; 
insert ('dampf',resultat,6); 
ergibt: 'Donaudampfschiff' in "resultat" 

Umwandlung numerische Variable/String: str 

Allgemeine Form: str (<numerischer ausdruck>,<string>); 

Erläuterung: Wandelt einen integer- oder real-Ausdruck in einen String um. Im Gegensatz zu einem numerischen Ausdruck kann mit einem String nicht mehr gerechnet werden; es sind jedoch weitgehende Manipulationen im Format möglich. Der <numerische ausdruck> kann wie in einer write-Prozedur schon vorformatiert übergeben werden. 

Beispiele:

x := 3.141592; 
str (x:2:4,resultat); 
ergibt: ' 3.1415' in "resultat" 
 
x := 23; 
str (x:5,resultat); 
ergibt: ' 23' in "resultat" 

Umwandlung String/numersiche Konstante: val 

Allgemeine Form: val (<string>,<numvar>,<code>); 

Erläuterung: Der <string> wird nach Zeichen untersucht, die eine sinnvolle numerische Konstante ergeben. Der gesamte <string> muß den Regeln über den Aufbau einer numerischen Konstante entsprechen, da sonst keine Umwandlung erfolgt. <numvar> ist eine integer- oder real-Variable, <code> ist eine integer-Variable. Hat die Umwandlung geklappt, steht in <numvar> die numerische Konstante, in <code> eine 0. Konnte die Umwandlung nicht erfolgen, so steht in <code> die Position des ersten Zeichens in <string>, das nicht paßte, der Inhalt von <numvar> ist undefiniert. 

("wort" ist vom Typ STRING, "betrag" vom Typ real, "error" vom Typ integer): 

Beispiele: 

wort := '2.7182'; 
val (wort,betrag,code); 
ergibt:
betrag = 2.7182 
code = 0 
wort := '2.3E7'; 
val (wort,betrag,code); 
ergibt:
betrag = 23000000 
code = 0 
wort := ' 23 ist eine Zahl'; 
val (wort,betrag,code); 
ergibt:
betrag = (undefiniert) 
code = 1 


Unterschied char - STRING 

Wie wir schon besprochen haben, darf man einer Variablen vom Typ STRING den sogenannten Leerstring zuweisen; das ist der "Nullstring" mit der Länge Null. Nun könnte man meinen, da STRING und char sehr nahe miteinander verwandt sind, ist es auch möglich, einer Variablen vom Typ char den Leerstring zuzuweisen, was ja auch sehr bequem wäre. Doch das geht leider nicht. Um zu verstehen, warum das so ist, sollen hier die beiden Methoden der Abspeicherung gezeigt werden. Wir gehen von einem String der Länge 1 und einer char- Variablen aus: 
PROGRAM test; 
  VAR c : char; 
      s : STRING [1]; 
BEGIN 
  c := 'A'; 
  s := 'A'; 
END. 
Typen char, STRING 

Da eine char-Variable nur aus einem Byte des Maschinenadressraumes besteht, muß (!) sie immer einen definierten Inhalt haben. Beim String wird das erste Byte im Maschinenadressraum nicht als zum String gehörig interpretiert, sondern als Information über den Status; deswegen ist hier der Leerstring möglich. Der Variablen "c" im Beispiel darf also nicht der Leerstring zugewiesen werden, da es ja auch kein Zeichen im Zeichensatz des Computers gibt, das kein Zeichen ist. 
 

 [ zurück | weiter ]
   (c) 2001 Schoenleber.com