Pages 49–51 · Markdown
As we discussed previously strings are series of characters stored as numbers in memory. Which number represents which character is usually governed by a standard. For NextBASIC this standard is a modified version of the ASCII standard that apart from characters, also defines tokens and UDGs. See Chapters 13 and 23 as well as Appendix A in order to better understand how characters, tokens and UDGs are stored. This chapter deals with ways of manipulating strings and reiterates some functions touched upon by previous chapters.
Given a string, a substring of it consists of some consecutive characters from it, taken in sequence. Thus “string” is a substring of “bigger string”, but “b sting” and “big reg” are not.
There is a notation called slicing for describing substrings, and this can be applied to arbitrary string expressions. The general form is:
string expression (start TO finish)
so that, for instance:
"abcdef"(2 TO 5)="bcde"
If you omit the start, then 1 is assumed; if you omit the finish then the length of the string is assumed. Thus:
"abcdef"( TO 5)="abcdef"(1 TO 5)="abcde"
"abcdef"(2 TO )="abcdef"(2 TO 6)="bcdef"
"abcdef"( TO )="abcdef"(1 TO 6)="abcdef"
(You can also write this last one as "abcdef"(), for what it's worth.)
A slightly different form misses out the TO and just has one number:
"abcdef"(3)="abcdef"(3 TO 3)="c"
Although normally both start and finish must refer to existing parts of the string, this rule is overridden by another one: if the start is more than the finish, then the result is the empty string. So:
"abcdef"(5 TO 7)
gives error 3 Subscript wrong because the string only contains 6 characters and 7 is too many, but:
"abcdef"(8 TO 7)="" (an empty string)
and:
"abcdef"(1 TO 0)="" (again, an empty string)
The start and finish must not be negative, or you get error B integer out of range. This next program is a simple one illustrating some of these rules.
10 a$="abcdef"
20 FOR n=1 TO 6
30 PRINT a$(n TO 6)
40 NEXT n
50 STOP
Type NEW when this program has been run and enter the next program:
10 a$="ABLE WAS I"
20 FOR n=1 TO 10
30 PRINT a$(n TO
10),a$((11-n) TO 10)
40 NEXT n
For string variables, we can not only extract substrings, but also assign to them. For instance, type:
a$="I'm the ZX Spectrum Next"
and then:
a$(5 TO 8)="******"
and:
PRINT a$
Notice how since the substring a$(5 TO 8) is only 4 characters long, only the first four stars have been used. This is a characteristic of assigning to substrings: the substring has to be exactly the same length afterwards as it was before. To make sure this happens, the string that is being assigned to it is cut off on the right if it is too long, or filled out with spaces if it is too short – this is called Procrustean assignment after the road bandit Procrustes who used to make sure that his victims fitted the bed by either stretching them out on a rack or cutting their feet off.
If you now try:
a$()="Hello there"
and:
a$;"."
You will see that the same thing has happened again (this time with spaces put in) because a$() counts as a substring.
a$="Hello there"
will do it properly.
Complicated string expressions will need parentheses around them before they can be sliced. For example:
"abc"+"def"(1 TO 2)="abcde"
("abc"+"def")(1 TO 2)="ab"
We saw earlier that the multiply (*) operator can be used for string replication. It's syntax is: a$*n (takes a string a$ as the first operand and a number n as the second operand, returning a string). If n has a fractional part then the string is replicated up to the character that represents the closest integer number to the product of n times the length of the original string. In other words, if you multiply a 7 character string by 1.5 times you will get the whole string and an additional 3 characters of it since 7 * 1.5 = 10.5. Finally, the sign of the number determines whether the result is mirrored or not. Consider the following examples:
"abcdefg"*2 | returns abcdefgabcdefg (two times the string) |
"abcdefg"*-1 | returns gfedcba (the string is inversed) |
"abcdefg"*1.5 | returns abcdefgabc |
If you follow a string expression a$ by brackets containing a modifier list in the format:
a$ [modifierlist]
you can transform the string in several useful ways. The modifierlist can be any of the following characters:
| + | convert lower case letters to upper case |
| - | convert upper case letters to lower case |
| < | strip leading spaces (and control characters) |
| > | strip trailing spaces (and control characters) |
| ~ | strip bit 7 (More about bit 7 in Chapter 23) terminator from last character of string |
| ^ | add bit 7 terminator to last character of string |
| (f$,r$) | replace any occurrences of characters present in f$ with the corresponding character from r$ (or delete if there is no corresponding character) |
The order of the modifiers is unimportant, except for (f$,r$) which, if present, must be the final modifier.
The following examples demonstrate what can ne achieved:
" Hello There! "[<+->]"
gives: hELLO tHERE!
as trailing and leading spaces are stripped via < and >and all lower case letters are converted to upper case with the + and upper case to lower case with the -.
"My typewriter is broken"[("nore","dro")]
returns My typwoito is borkd as r$ doesn't have a corresponding letter for the e of f$ so all of them are deleted, all o are replaced by r and all r are replaced by o
Note that it is possible to slice a modified string, or modify a sliced string, since both () and [] continue to be evaluated following a string argument until there are no further opening parentheses or brackets. For example:
a$(5)[-](3 TO 7)[<]
is perfectly valid.
If need be, (for example to easily prepare strings to be passed to functions VAL or VAL$ – See next Chapter) we can tokenise, that is to convert NextBASIC reserved words to their single code equivalents (tokens) – without syntax checking– the contents of a string expression a$ by enclosing it in braces {} like so:
{a$}
For example:
{"sin (pi/4)"} | returns a string "SIN (PI/4)", including the tokens SIN (code 178) and PI (code 167) |
VAL{"sin (pi/4)"} | gives 0.7071 |
ZX Spectrum Next User Manual, 3rd Edition (ISBN 978-1-5272-5496-1), written and illustrated by Phoebus R. Dokos. Copyright © 2020-2024 Phoebus Dokos / SpecNext Ltd. Licensed under CC BY-NC-SA 4.0. This is a transcription and can contain errors; check any doubt against the printed page.