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

Action!
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) …

Prvokname(0)name(1)name(2)name(3)name(4)name(5)
Obsah5Atari

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:

Action!
; 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")
RETURN

Preklad 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 ant

Ako to funguje

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ý textprepíše sa pamäť za poľom, bez hlásenia
zámena poradia v SCopyskopí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

  1. Načítaj meno cez InputS a vypíš ho odzadu.
  2. Spočítaj, koľkokrát je v načítanom texte písmeno a.
  3. Načítaj dve slová a vypíš ich v abecednom poradí.

Zhrnutie

Späť: 18. Polia · Ďalej: 20. Ukazovatele