Rozdział 21 - Podłańcuchy

Dla danego łańcucha tekstowego jego podłańcuch składa się z kilku kolejnych znaków tego łańcucha, wybranych jeden po drugim. Zatem "STRING" jest podłańcuchem "BIGGER STRING", lecz "B STRING" i "BIG REG" nie są.

Istnieje notacja (czyli sposób zapisu - przyp. tłum.) zwana slicingiem do opisu podłańcuchów, którą można zastosować do dowolnych wyrażeń łańcuchowych. Postać ogólna jest następująca:

wyrażenie łańcuchowe (start TO koniec)

zatem przykładowo

"ABCDEF" (2 TO 5) = "BCDE"

Jeśli pominiesz start, to zostanie zostanie wstawione w to miejsce 1; jeśli pominiesz koniec, wtedy pojawi się tam długość całego łańcucha. Na przykład:

"ABCDEF" ( TO 5) = "ABCDEF" (1 TO 5) = "ABCDE"
"ABCDEF" (2 TO ) = "ABCDEF" (2 TO 6) = "BCDEF"

oraz

"ABCDEF" ( TO ) = "ABCDEF" (1 TO 6) = "ABCDEF"

(ostatni przykład możesz również zapisać jako "ABCDEF" (), ale czemu miałoby to służyć?)

Jeśli opuścimy słówko TO i pozostawimy tylko jedną liczbę, otrzymamy znak na tej pozycji:

"ABCDEF" (3) = "ABCDEF" (3 TO 3) = "C"

Chociaż zwykle zarówno start jak i koniec muszą odwoływać się do elementów łańcucha, to reguła ta jest zastępowana przez inną: jeśli pozycja startowa jest większa od końcowej, to wynikiem będzie pusty łańcuch. Zatem:

"ABCDEF" (5 TO 7)

daje błąd 3 (błąd indeksu), ponieważ ten łańcuch zawiera tylko 6 znaków, a 7 to już za dużo, lecz:

"ABCDEF" (8 TO 7) = ""

oraz

"ABCDEF" (1 TO 0) = ""

 

Pozycje startu i końca nie powinny być ujemne, inaczej otrzymasz błąd B.

Następny program tworzy B$ równe A$, lecz z pominięciem końcowych spacji:

10 INPUT A$
20 FOR N=LEN A$ TO 1 STEP -1
30 IF A$(N)<>"" THEN GOTO 50
40 NEXT N
50 LET B$=A$( TO N)
60 PRINT """";A$;"""","""";B$;""""
70 GOTO 10

Zauważ, że w przypadku A$ składającego się z samych spacji w wierszu 50 mamy N = 0 i A$( TO N) = A$(1 TO 0) = "".

 

Dla zmiennych łańcuchowych możemy nie tylko wydobywać podłańcuchy, lecz również przypisywać im je. Na przykład wpisz:

LET A$="ALI KOTEK TO MLOTEK"

a następnie:

LET A$(5 TO 9)="12345678"

i

PRINT A$

Zauważ, iż skoro podciąg A$(5 TO 9) ma długość tylko 5 znaków, to tylko pierwsze pięć cyfr, 12345, zostało użyte. Jest to cecha charakterystyczna przypisywania do podłańcuchów: podłańcuch musi po operacji posiadać taką samą długość jak przed nią. Aby się upewnić, iż tak właśnie się stanie, przypisywany łańcuch zostaje przycięty z prawej strony, gdy jest zbyt długi, lub zostaje dopełniony spacjami, gdy jest za krótki - nazywa się to dopasowaniem Prokrustesa - nazwa pochodzi od karczmarza Prokrustesa (lub Prokrustosa), który miał zwyczaj upewniać się, iż jego goście dokładnie pasują do łóżka albo naciągając ich na kole tortur, albo przycinając im nogi (czasem też głowę - przyp. tłum.).

 

Jeśli teraz spróbujesz:

LET A$()="TATA RATA"

i

PRINT A$;"."

to zobaczysz, iż znów to się stało (tym razem z dopełnieniem spacjami), ponieważ A$() liczy się jako podłańcuch.

Poprawnie robimy to tak:

LET A$="TATA RATA"

 

Slicing może być traktowany jako operacja o priorytecie 12, zatem przykładowo:

LEN "ABCDEF"(2 TO 5) = LEN("ABCDEF"(2 TO 5)) = 4

Przed podziałem na podłańcuchy skomplikowane wyrażenia łańcuchowe należy obłożyć nawiasami. Na przykład:

"ABC"+"DEF"(1 TO 2) = "ABCDE"
("ABC"+"DEF")(1 TO 2) = "AB"

 

 

Podsumowanie  

Slicing, użycie TO. Uwaga: notacja ta nie jest standardowa.

 

 

Ćwiczenia

  1. Niektóre dialekty języka BASIC (nie ZX81 BASIC) posiadają funkcje zwane LEFT$, RIGHT$, MID$ oraz TL$.

LEFT$(A$,N) daje podłańcuch łańcucha A$ złożony z pierwszych N znaków.

RIGHT$(A$,N) daje podłańcuch łańcucha A$ złożony z N końcowych znaków.

MID$(A$,N1,N2) daje podłańcuch łańcucha A$ składający się z N2 znaków począwszy od pozycji N1-tej.

TL$(A$) daje podłańcuch łańcucha A$ składający się ze wszystkich jego znaków za wyjątkiem pierwszego.

Jak byś zapisał je w ZX81 BASIC? Czy twoje rozwiązanie działa poprawnie z łańcuchami o długości 0 lub 1?

 

 

  1. Wypróbuj ciąg rozkazów:

LET A$="X*+*Y"
LET A$(2)=CHR$ 11  [znak cudzysłowu]
LET
A$(4)=CHR$ 11
PRINT
A$

Teraz A$ jest łańcuchem zawierającym wewnątrz znaki cudzysłowu! Jeśli będziesz wystarczająco wytrwały, to już nic cię nie powstrzyma przed robieniem tak, lecz jasne jest, iż gdybyś pierwotnie wpisał:

LET A$="X"+"Y"

to fragment na prawo od znaku równosci zostałby potraktowany jako wyrażenie łańcuchowe nadając A$ wartość "XY".

Teraz wpisz

LET B$="X""+""Y"

Przekonasz się, iż chociaż A$ i B$ wyglądają tak samo na wydruku, to równe nie są - spróbuj:

PRINT A$=B$

B$ zawiera jedynie obrazy znaków cudzysłowu (o kodach 192), natomiast A$ posiada prawdziwe znaki cudzysłowu (o kodzie 11).

 

 

  1. Uruchom program:

  10 LET A$="LEN ""ABDC"""
100 PRINT A$;" = ";VAL A$

To nie zadziała, ponieważ VAL nie potraktuje obrazu cudzysłowu "" jako cudzysłowu łańcucha.

Wprowadź kilka dodatkowych wierszy pomiędzy 10 i 100, które zastąpią znaki obrazu cudzysłowu w A$ przez cudzysłowy łańcucha (otrzymasz je przy pomocy CHR$ 11) i spróbuj jeszcze raz.

Takie same zmiany wykonaj w programie z ćwiczenia 3 w rozdziale 9 i poeksperymentuj z nim.

 

 

  1. Ten podprogram usuwa każde wystąpienie łańcucha "CARTHAGO" z A$.

1000 FOR N=1 TO LEN A$-7
1020 IF A$(N TO N+7)="CARTHAGO" THEN LET A$(N TO N+7)="********"
1030 NEXT N
1040 RETURN

Napisz program nadający A$ różne wartości (np. "DELENDA EST CARTHAGO.") i wywołujący ten podprogram.

 



List do administratora Serwisu Edukacyjnego Nauczycieli I LO

Twój email: (jeśli chcesz otrzymać odpowiedź)
Temat:
Uwaga: ← tutaj wpisz wyraz  ilo , inaczej list zostanie zignorowany

Poniżej wpisz swoje uwagi lub pytania dotyczące tego rozdziału (max. 2048 znaków).

Liczba znaków do wykorzystania: 2048

 

W związku z dużą liczbą listów do naszego serwisu edukacyjnego nie będziemy udzielać odpowiedzi na prośby rozwiązywania zadań, pisania programów zaliczeniowych, przesyłania materiałów czy też tłumaczenia zagadnień szeroko opisywanych w podręcznikach.



   I Liceum Ogólnokształcące   
im. Kazimierza Brodzińskiego
w Tarnowie

©2018 mgr Jerzy Wałaszek

Dokument ten rozpowszechniany jest zgodnie z zasadami licencji
GNU Free Documentation License.