19. Reťazce: CHAR ARRAY
Na čo to je
Reťazec je text uložený v programe: meno hráča, hlásenie, riadok zo súboru. V Action! je to obyčajné pole znakov s jedným pravidlom navyše.
Ako sa to píše
CHAR ARRAY name="Atari" ; reťazec s textom
CHAR ARRAY buffer(40) ; prázdne miesto pre reťazec: dĺžka + 39 znakov
Pravidlo: prvok (0) je dĺžka textu, znaky sú v prvkoch (1), (2) …
| Prvok | name(0) | name(1) | name(2) | name(3) | name(4) | name(5) |
|---|---|---|---|---|---|---|
| Obsah | 5 | A | t | a | r | i |
Z toho plynie, že reťazec môže mať najviac 255 znakov (viac sa do jedného bajtu dĺžky nezmestí) a že pole pre text s n znakmi potrebuje n+1 bajtov.
Knižnica má na reťazce štyri rutiny:
| Rutina | Čo robí |
|---|---|
SCopy(kam, odkiaľ) | skopíruje celý reťazec |
SCopyS(kam, odkiaľ, od, do) | skopíruje časť: znaky s číslami od až do |
SAssign(kam, odkiaľ, od, do) | vloží reťazec do iného na pozície od až do |
SCompare(a, b) | porovná dva reťazce; vráti záporné číslo, nulu alebo kladné číslo |
Celý program
Súbor examples/strings.act:
; Strings: texts in CHAR ARRAYs
PROC Order(CHAR ARRAY a, b) ; a string as a parameter
INT result
result=SCompare(a, b)
Print(a)
IF result<0 THEN
Print(" comes before ")
ELSEIF result=0 THEN
Print(" is the same as ")
ELSE
Print(" comes after ")
FI
PrintE(b)
RETURN
PROC Main()
CHAR ARRAY name="Atari" ; a string with its text
CHAR ARRAY copy(20), part(20), line(40)
BYTE i
Print("The text: ") PrintE(name)
Print("Its length: ") PrintBE(name(0))
Print("First letter: ") Put(name(1)) PutE()
Print("Spelled: ")
FOR i=1 TO name(0)
DO
Put(name(i)) Put(' )
OD
PutE()
SCopy(copy, name) ; copy the whole string
copy(1)='S ; change one character
Print("Changed copy: ") PrintE(copy)
Print("The original: ") PrintE(name)
SCopyS(part, "Action! language", 1, 7)
Print("A part: ") PrintE(part)
SCopy(line, "Hello, ") ; join two strings
SAssign(line, name, line(0)+1, line(0)+name(0))
Print("Joined: ") PrintE(line)
Order("apple", "banana")
Order("pear", "pear")
Order("zebra", "ant")
RETURNPreklad a spustenie
action26 strings.act --simČo uvidíš
The text: Atari
Its length: 5
First letter: A
Spelled: A t a r i
Changed copy: Stari
The original: Atari
A part: Action!
Joined: Hello, Atari
apple comes before banana
pear is the same as pear
zebra comes after antAko to funguje
name(0)je dĺžka,name(1)prvý znak. SlučkaFOR i=1 TO name(0)prejde všetky znaky – to je bežný spôsob, ako spracovať text znak po znaku.SCopy(copy, name)– cieľ je prvý, zdroj druhý. Tak je to pri všetkých rutinách na reťazce.copy(1)='Smení jeden znak ako prvok poľa. Originálnameostáva nedotknutý, lebocopyje vlastné pole.SCopyS(part, "Action! language", 1, 7)vyberie znaky 1 až 7. Zdrojom môže byť aj text priamo v úvodzovkách.- Spojenie dvoch reťazcov Action! nemá ako jednu rutinu. Skladá sa zo
SCopy(prvá časť) aSAssign(druhá časť za koniec prvej).line(0)+1je prvá voľná pozícia;SAssignreťazec podľa potreby predĺži. SCompareporovnáva podľa abecedy – presnejšie podľa kódov znakov. Na presnej hodnote výsledku nezáleží, len na tom, či je záporný, nulový alebo kladný.
Procedúra Order ukazuje reťazec ako parameter: CHAR ARRAY a bez veľkosti. Ako každé pole sa nekopíruje.
Časté chyby
| Čo sa stalo | Čo sa stane |
|---|---|
porovnanie cez = (IF a=b THEN) | prekladač mlčí; porovnajú sa adresy polí, nie texty – dva rôzne reťazce s rovnakým textom „nie sú rovnaké“ |
priradenie textu do poľa s veľkosťou (buffer="hello") | error ACT010: illegal assignment: cannot assign to CHAR ARRAY – použi SCopy |
| cieľ je menší ako kopírovaný text | prepíše sa pamäť za poľom, bez hlásenia |
zámena poradia v SCopy | skopíruje sa opačným smerom |
veľké a malé písmená pri SCompare | "Apple" a "apple" sú rôzne; veľké písmená majú menšie kódy, takže "Zebra" je pred "ant" |
Na porovnanie textov teda vždy SCompare(a, b)=0, nikdy a=b.
DEFINE STRING="CHAR ARRAY" z kapitoly 17 robí deklarácie reťazcov čitateľnejšími: STRING name(40).
Vyskúšaj si
- Načítaj meno cez
InputSa vypíš ho odzadu. - Spočítaj, koľkokrát je v načítanom texte písmeno
a. - Načítaj dve slová a vypíš ich v abecednom poradí.
Zhrnutie
- Reťazec je
CHAR ARRAY; prvok 0 je dĺžka, znaky sú od prvku 1. - Pole pre
nznakov musí mať aspoňn+1bajtov. SCopykopíruje,SCopySvyberá časť,SAssignvkladá,SCompareporovnáva.- Cieľ je vždy prvý parameter.
- Reťazce sa neporovnávajú znakom
=a nepriraďujú znakom=.
Späť: 18. Polia · Ďalej: 20. Ukazovatele