Řetězce
Zatím jsme používali řetězce jen na komentování výsledků v příkazech Writeln. Řetězce, tedy pole znaků, mohou ale sloužit k lecčemu a některé z úloh formulovaných zcela přirozeně pro řetězce jsou, nahlíženo okem informatiků, docela složité. Jako rekreaci doporučuji si prohlédnout třeba nějakou literaturu k hledání nejdelšího společného podřetězce dvou řetězců, úlohu, která může být docela užtečná třeba u analýzy DNA. Právě pro rozsáhlost problému budeme řetězce studovat jen velmi utilitárně a vyhneme se mnoha detailům a problémům.
Řetězcové konstanty
Již víme vše o znacích a řetězce jsou
speciální pole znaků. Protože by bylo nepříjemné psát
něco jako
('A','h','o','j',' ','l','i','d','i','!')
lze v Pascalu zapisovat řetězcové konstanty takto 'Ahoj
lidi!'.
Writeln('''Apostrof uvnitr retezce ('') se pise jako dva ('''')''');
Vypíše: 'Apostrof uvnitr retezce (') se pise jako dva ('')'
Typ String
Naneštěstí přes všechnu snahu o pravidelnost v Pacsalu se ukázalo, že užitečné věci jsou nepravidelné. Příkladem jsou třeba řetězce. Jde o složitý problém. Již jsme viděli, že kvůli spolupráci s OS mají speciální význam pole znaků se spodní mezí intervalu indexů 0. Z historických důvodů je jazyce Object Pascal připraveno několik variant řetězcových typů. Povíme jen něco málo o typu string.
var s,t : string; i,j : integer; begin s := 'ABCD1234'; {Přiřazení konstanty do řetězce} t := s; {Přiřazení hodnoty s do t} Writeln(t); {Vypíše 'ABCD1234'} t := copy(s,2,3); {Přiřazení výsledku funkce do proměnné, kus počínaje druhým dlouhý tři} t[1] := 'B'; Writeln(t); {Vypíše 'BCD'} Delete(s,1,4); {Vypustí 'ABCD'} Writeln(s); {Vypíše '1234'} t := '..'+s; {Složení řetězce z kousků} Writeln(t); {Vypíše '..1234'} Insert('xx',t,2); Writeln(t); {Vypíše '.xx.1234'} Writeln('Retezec '''+t+''' ma delku ',Length(t)); {délka řetězce ve znacích} Writeln('Podretezec ''23'' se nachazi na indexu ', Pos('23',t), {nalezení polohy podřetězce jinak 0} ' retezce '+t); Setlength(t,20); t[20]:='6'; Writeln(t); {Vypíše '.xx.1234 6' ale ty mezery nejsou mezery, jak uvidíme:} for i:=1 to length(t) do Write('#',ord(t[i])); {Vypíše '#46#120#120#46#49#50#51#52#0#0#0#0#0#0#0#0#0#0#0#54'); } str(Pi:20:10,s); {Nacpi Pi do retezce} Writeln(#10#10#10#10+s); {čtyři novéřádky a Pi} val(copy(s,11,10),i,j); {převeď řetězec na číslo} Writeln(i); {Vypíše 1415926536} Readln; end.
Ještě máme po ruce další spoustu procedur a funkcí např. UpperCase
Velmi důležitá je někdy funkce
procedure Val(S; var V; var Code: Integer)
která umí do celočíselné nebo reálné
proměnné V dosadit hodnotu zapsanou v řetězci. Code je 0
pokud nenastanou problémy, jinak je to index problematického
znaku v řetězci.
Interně je typ string podobný poli znaků s otevřeným koncem,
první znak řetězce (pokud má délku >0) se ale nachází
na indexu 1. Proto SetLength(Retezec,Delka)
znamena výjimečně, že použití Retezec[Delka]
je OK.
Proceduru SetLength(Retezec,Delka) použijeme především tehdy, pokud chceme pomocí indexů pracovat s jednotlivými znaky řetězce (buď vědomě za jeho aktuální délkou, nebo ji jednoduše nezáme). V rámci přiřazovacího příkazu a při volání systémových funkcí pracujících s řetězci tuto funkci folat smozřejmě nemusíme.
Ve výjimečných případech se může hodit vědět, že řetězec s neproměnnou délkou se deklaruje jako
type tJmenaReckychPismen = string [10]; //zadne neni delsi
Jde ale o přežitek z minulosti, třeba jen tím, že v hranatých závorkách smíme uvést jen číslo do 255.