5172


11. OPERACJE NA ŁAŃCUCHACH ZNAKOWYCH

11.1. Opis typu i deklarowanie zmiennych łańcuchowych

Typ łańcuchowy o nazwie string opisuje strukturę danych, złożoną z 255 elementów typu Char. Jest ona przeznaczona do pamiętania łańcuchów znakowych, czyli fragmentów tekstu. W jednej zmiennej typu string można przechować najwyżej 255 znaków. Nie wszystkie stojące do dyspozycji miejsca muszą być wykorzystane. Odróżniamy długość deklarowaną zmiennej łańcuchowej od jej długości rzeczywistej.

Format zmiennej łańcuchowej w pamięci ilustruje rysunek:

L

L[0]

L[1]

L[2]

L[3]

L[4][

L[5]

L[6]

L[7]

L[8]

L[9]

...

L[255]

#7

'P'

'r'

'o'

'g'

'r'

'a'

'm'

...

Szczególną rolę odgrywa zerowa pozycja zmiennej łańcuchowej. Przechowuje ona zawsze znak o numerze równym aktualnej długości łańcucha. W podanym przykładzie będzie tam się znajdować znak #7.

Deklaracja zmiennej łańcuchowej:

var Napis: string;

Nadanie zmiennej wartości początkowej:

const L:string = 'Program';

11.2. Własne typy łańcuchowe

Można zdefiniować własny typ łańcuchowy o odpowiednio mniejszej długości deklarowanej. Na przykład:

type S_80 = string[80];

Zmienna typu S_80 zajmuje 81 bajtów pamięci (bajt zerowy + 80 bajtów deklarowanych).

11.3. Stałe łańcuchowe

Jawne stałe łańcuchowe umieszcza się pomiędzy dwoma apostrofami:

'Turbo Pascal'

'Adam Mickiewicz'

'127'

'B:\JEZYKI\TP\TURBO.EXE'

''

Dwa kolejne apostrofy reprezentują łańcuch pusty. Jego aktualna długość wynosi 0. W bajcie zerowym takiego łańcucha znajduje się znak #0.

Definiowane stałe łańcuchowe są przydatne, gdy w programie często występuje taki sam łańcuch o znacznej długości:

const C1='Nacisnij klawisz <Enter>';

C2='Wprowadz liczbe: ';

W dowolnym miejscu bloku, w którym definicja obowiązuje, nazwa C1 będzie rozumiana jako wartość łańcuchowa 'Nacisnij klawisz <Enter>', a nazwa C2 - jako wartość łańcuchowa 'Wprowadz liczbe: `.

11.4. Wykorzystanie instrukcji przypisania

Łańcuchy krótsze od deklarowanej długości zmiennej, lub tej samej jak ona długości, są kopiowane bez zmian. Natomiast, gdy chcemy przypisać łańcuch dłuższy, niż na to pozwala deklarowana długość zmiennej, to końcowe znaki łańcucha zostają po prostu obcięte:

type S20=string[20]'

S12=string[12];

var Nazwisko: S20;

Miasto:S12;

begin

Nazwisko:='Kowalski'; {Nazwisko='Kowalski'}

Miasto:='Konstantynopol';{Miasto='Konstantynop'}

end.

Do łańcucha wolno przypisać znak. Na przykład, jeżeli:

var Z:Char; L:string;

to prawidłowe jest przypisanie:

L:=Z;

W wyniku tej operacji L będzie łańcuchem o aktualnej długości równej 1. Natomiast przypisanie odwrotne jest niemożliwe, bo zmienna typu Char ma do dyspozycji jeden bajt pamięci, podczas gdy zmienna typu string wymaga 256 bajtów pamięci!

11.5. Odwoływanie się do elementów łańcucha

Do elementów (poszczególnych znaków) łańcucha można odwoływać się tak samo, jak do elementów jednowymiarowej tablicy. Takie odwołania mogą być przeznaczone zarówno do zapisu, jak odczytu znaków..

Chcąc odczytać K-ty znak łańcucha Lancuch i zapamiętać ten znak w zmiennej znakowej C, napiszemy::

C:=Lancuch[K];

Przykład: Procedura wyprowadzająca łańcuch W drukiem rozstrzelonym:

procedure Pisz_szeroko(W:string);

begin

for K:=1 to Length(W) do begin

Write W[K];

Write(#32);

end;

end;

11.6. Operacja sklejania łańcuchów

Chcąc skleić dwa lub więcej łańcuchów, czyli połączyć je w jeden wspólny łańcuch, stosujemy operator sklejania (konkatenacji), który wygląda tak samo, jak operator dodawania. Otrzymane w ten sposób wyrażenie łańcuchowe można przypisać do zmiennej łańcuchowej. Oczywiście wynik takiej operacji zależy od porządku składników. Argumentami operacji sklejania mogą być również znaki, np.:

const C1='Jan'; C2='Kowalski';

var S1,S2: string;

begin

S1:=C1+#32+C2; {S1='Jan Kowalski'}

S2:=C2+#32+C1; {S2='Kowalski Jan'}

end;

11.7. Porównywanie łańcuchów

Porównywanie łańcuchów odbywa się za pomocą operatorów relacyjnych, działających na łańcuchach:

=,<>,<,>,<=,>=

Łańcuch mniejszy, to ten, który na wcześniejszej pozycji ma znak o mniejszym numerze porządkowym. Wynika stąd na przykład, że łańcuch pisany wielkimi literami jest mniejszy od tego samego łańcucha pisanego małymi literami.

Łańcuchy są równe, gdy mają tę sama liczbę znaków i jednocześnie znaki na każdej ich pozycji są jednakowe.

W przykładzie 11.5 pokazano wykorzystanie operatora większości w procedurze, która sortuje zawartość tablicy łańcuchów w porządku alfabetycznym. W programie pokazano także sposób zainicjowania tablicy łańcuchów przy jej deklarowaniu.

program Ex11_5;

uses Crt;

type Tab=array [1..6] of string;

const T:Tab=('Tomasz','Jacek','Adam','Robert','Ewa','Beata');

procedure PokTab(var T:Tab);

var I:Integer;

begin

for I:=Low(T) to High(T) do Writeln(T[I]);

Writeln;

end;

procedure Sortuj(var T:Tab);

var K,J:Integer;

Kopia:string;

begin

for K:=Low(T) to High(T)-1 do

for J:=K+1 to High(T) do

if T[K]>T[J] then begin

Kopia:=T[K];

T[K]:=T[J];

T[J]:=Kopia;

end;

end;

begin

Clrscr;

Poktab(T);

Sortuj(T);

Poktab(T);

Readln;

end.

11.8. Funkcje i procedury standardowe operujące na łańcuchach

Poniżej pokazano nagłówki definicji i krótki opis działania standardowych funkcji i procedur Turbo Pascala, przeznaczonych do operacji na łańcuchach.

function Length(S:string):Integer;

Zwraca aktualną długość łańcucha S.

function Concat(S1,S2, . . . Sn):string;

Zwraca łańcuch będący sklejeniem kolejnych argumentów S1, S2, … Sn. Zamiast tej funkcji można zastosować operatory sklejania `+'.

function

Copy(S:string;Poz:Integer;D:Integer):string;

Łańcuch wynikowy jest wycinkiem łańcucha S zaczynającym się od pozycji Poz, mającym długość określoną przez argument D.

function Pos(S1,S2:string):Byte;

Bada, czy w łańcuchu S2 znajduje się podłańcuch S1. Jeżeli nie ma takiego podłańcucha, zwraca wartość 0; w przeciwnym przypadku zwraca numer pozycji S2, od której rozpoczyna się pierwsze wystąpienie podłańcucha S1.

procedure

Delete(var S:string; Poz:Integer; D:Integer);

Wycina podłańcuch z łańcucha S. Wycięty podłańcuch zaczyna się od pozycji Poz i ma D znaków. Jeżeli Poz jest większa od aktualnej długości S, to postać łańcucha S nie ulega zmianie.

procedure

Insert(S1:string; var S2:string; N:Integer);

Wstawia do łańcucha S2 podłańcuch S1, począwszy od pozycji następnej za znakiem N-tym łańcucha S2. Jeżeli N jest większe od aktualnej długości S2, to podłańcuch S1 zostaje doklejony na końcu S2.

procedure Str(X; var S:string);

Przekształca daną X dowolnego typu liczbowego na łańcuch znaków S, reprezentujący odpowiedni zapis dziesiętny tej danej. Pisząc argument X, można stosować parametry określające liczbę pozycji zapisu i liczbę miejsc po kropce dziesiętnej, podobnie jak w instrukcjach Write, Writeln.

procedure Val(S:string; var X; var Kod:Integer);

Przekształca łańcuch znakowy S, stanowiący poprawny zapis dowolnej liczby, na liczbę X, będącą zmienną odpowiedniego typu liczbowego. Jeżeli Łańcuch S był poprawnym zapisem liczby, to argument wyjściowy Kod przyjmuje wartość 0; w przeciwnym przypadku Kod jest numerem pozycji łańcucha S, na której wykryto pierwszy błąd zapisu.

11.9. Przykłady wykorzystania standardowych funkcji i procedur łańcuchowych

Przykład 11.6. Zastosowanie procedury Val do programowej kontroli formatu liczby

procedure CzytKontrol(var X:Real);

var S:string[80];

Kod:Integer;

begin

repeat

Write('Podaj liczbe: ');

Readln(S);

Val(S,X,Kod);

if Kod<>0 then

Writeln('Blad na pozycji ',Kod);

until Kod=0;

end;

Przykład 11.7. Znajdowanie liczby wystąpień podłańcucha w łańcuchu

program Ex11_7;

uses Crt;

type S_80 = string[80];

const L:S_80 = 'Adam Kowalski i Janina Kowal-Kowalska';

var P:S_80;

W:Byte;

function IlePodlanc(P,L:string):Byte;

{Zwraca liczbę wystąpień podłańcucha P w łańcuchu L.}

var Licznik:Byte;

Pozycja,D:Integer;

begin

D:=Length(P); {Długość podłańcucha}

Licznik:=0;

while Pos(P,L)<>0 do begin

Pozycja:=Pos(P,L); {Pozycja 1. wystąpienia P}

Licznik:=Licznik+1; {Licznik wystąpień P w L}

Delete(L,Pozycja,D); {Usuwanie kolejnego P}

end;

IlePodlanc:=Licznik;

end;

begin

Clrscr;

Writeln(L);

Write('Wpisz szukany podlancuch: ');

Readln(P);

W:=IlePodlanc(P,L);

Write('Liczba wystapien: ', W);

Readln;

end.

Przykładowa zmiana argumentu L podczas liczenia wystąpień podłańcucha `Kowal':

Adam Kowalski i Janina Kowal-Kowalska {postać początkowa}

Adam ski i Janina Kowal-Kowalska (po kroku nr 1}

Adam ski i Janina -Kowalska {po kroku nr 2}

Adam ski i Janina -ska {po kroku nr 3}

Przykład 11.8. Użycie funkcji Length do centrowania tekstu w elementach tablicy łańcuchów

program Ex11_8;

uses Crt;

type S_80 = string[80];

Tab = array [1..6] of S_80;

const T:Tab=

('Ordinal types are a subset of simple types.',

'All simple types other than real types',

'are ordinal types.',

'Except for integer-type values,',

'the first value of every ordinal type',

'has ordinality 0.');

procedure Poktab(var T:Tab);

var K:Integer;

begin

for K:=Low(T) to High(T) do Writeln(T[K]);

Writeln;

end;

procedure Centruj(var T:Tab);

var K:Integer;

S:string;

begin

for K:=Low(T) to High(T) do begin

S:='';

repeat

S:=S+#32;

until 2*Length(S)+Length(T[K])>=79;

T[K]:=S+T[K];

end;

end;

begin

Clrscr;

Centruj(T);

PokTab(T);

Readln;

end.

W procedurze Centruj, łańcuch S, początkowo pusty, jest konstruowany przez kolejne doklejanie pojedynczych spacji w zagnieżdżonej pętli repeat-until. Dla każdego elementu T[K] doklejanie spacji kończy się, gdy suma podwójnej długości łańcucha S oraz długości łańcucha T[K] osiągnie wartość, odpowiadającą liczbie znaków, mieszczących się w jednym wierszu ekranu. Ma to miejsce po spełnieniu relacji:

2*Length(S)+Length(T[K]}>=79

W rezultacie, fragmenty tekstu, zawarte w kolejnych elementach tablicy, zostaną wypisane symetrycznie względem środka ekranu, jak pokazano poniżej.

Ordinal types are a subset of simple types.

All simple types other than real types

are ordinal types.

Except for integer-type values,

the first value of every ordinal type

has ordinality 0.

83



Wyszukiwarka

Podobne podstrony:
04 Przestrzen nazw domenid 5172 Nieznany (2)
5172
M 5172 Lace top dress
5172
L 5172 Lace top dress
04 Przestrzen nazw domenid 5172 Nieznany (2)

więcej podobnych podstron