Page 1 of 1

Another BASIC noob question (DIM)

Posted: Tue Jan 03, 2023 9:43 pm
by beanz
Please see program below (I have something similar to this in my main program)

in this example the results I want should be printed out as follows

london
6
bath
4
manchester
10
southport
9

(with the numbers reflecting the length of the city name)

however the program below reports the city lengths all as 10 (as set in the dim statement)...how can I get the results I want (above)..what am I doing wrong...

5 DIM Z$(4,10)
15 FOR N=1 TO 4 STEP 1
20 READ Z$(N)
30 PRINT Z$(N)
40 PRINT LEN Z$(N)
50 NEXT N
60 DATA "LONDON", "BATH", "MANCHESTER", "SOUTHPORT"

Re: Another BASIC noob question (DIM)

Posted: Tue Jan 03, 2023 9:52 pm
by WhatHoSnorkers
You're doing nothing wrong. It's just not quite working how you want.

So the strings in the DATA statements are copied into a fixed length string array. So the lengths are always going to be 10.

If you try

15 FOR N=1 TO 4 STEP 1
20 READ Z$
30 PRINT Z$
40 PRINT LEN Z$
50 NEXT N
60 DATA "LONDON", "BATH", "MANCHESTER", "SOUTHPORT"

It will work as you want.


Image

Re: Another BASIC noob question (DIM)

Posted: Tue Jan 03, 2023 10:39 pm
by Bubu
In a string array, all the strings have the same, fixed length. The DIM statement has an extra number (the last one) to specify this length. When you write down a subscripted variable for a string array, you can put in an extra number, or a slicer, to correspond with the extra number in the DIM statement.

Source:
https://worldofspectrum.org/ZXBasicManu ... hap12.html

Re: Another BASIC noob question (DIM)

Posted: Tue Jan 03, 2023 10:51 pm
by AndyC
To be more formal, string arrays in Sinclair BASIC are Procrustean. That is, strings you store into it are either chopped short or extended with spaces such that they are always the same length. This is because it makes the implementation simpler.

Not a lot you can do about it in BASIC short of writing code to remove trailing spaces before calculating the length (or code to calculate the length ignoring trailing spaces, depending on what you need to achieve)

Re: Another BASIC noob question (DIM)

Posted: Wed Jan 04, 2023 2:57 am
by beanz
Thanks guys

Re: Another BASIC noob question (DIM)

Posted: Wed Jan 04, 2023 10:15 am
by WhatHoSnorkers
Sometimes the fixed length thing is useful, like in a text adventure. I typed one in once and I saw a bone. I said "TAKE BONE". And it said "You do not see a BONE".

Because the object I typed in was "BONE". The object in the game was "BONE ". And they are NOT the same.
One way around that sort of thing is to assign the "object you type in" to a fixed length string, and let it be padded.
Or compare with objects up to the length of the string I typed in.... but that will mean you can't have BONE, BONESAW, HAT, HATCHET, CAR, CARBINE and so on.

Re: Another BASIC noob question (DIM)

Posted: Wed Jan 04, 2023 11:21 am
by TMD2003
AndyC wrote: Tue Jan 03, 2023 10:51 pm Not a lot you can do about it in BASIC short of writing code to remove trailing spaces before calculating the length
...which is something I did, in Corona Capers. @beanz, you want to know how it's done - examine the listing. I'll even tell you it's at line 7590 in the main program ("COVID-22" on the tape). Examine the array C$ to see its variable-length contents padded with spaces, all of which start at length 18.

Now I've told you how it's done, you should be able to adapt it for your own needs. Mush!

Re: Another BASIC noob question (DIM)

Posted: Wed Jan 04, 2023 11:23 am
by RST#08
If you want to use arrays (and there are very good reasons why you might want to do this), you might want to consider embedding the length of the string into each array item as a 'hidden' CODE byte.

You then use slicing, something that ZX BASIC makes very easy. It's perhaps easier to show this rather than explain! There is a good example of this technique on pages 130-131 of this book:

https://spectrumcomputing.co.uk/entry/2 ... X_Spectrum

The example provided constructs the string array and embedded length bytes using INPUT, but there is no reason why you couldn't use READ, DATA etc. to do this.

Hope this helps :D

P.S. First post here :dance but I previously did one or two posts on the 'old' WOS using the same username.

Re: Another BASIC noob question (DIM)

Posted: Wed Jan 04, 2023 1:39 pm
by beanz
TMD2003 wrote: Wed Jan 04, 2023 11:21 am ...which is something I did, in Corona Capers. @beanz, you want to know how it's done - examine the listing. I'll even tell you it's at line 7590 in the main program ("COVID-22" on the tape). Examine the array C$ to see its variable-length contents padded with spaces, all of which start at length 18.

Now I've told you how it's done, you should be able to adapt it for your own needs. Mush!
Thanks, I'll take a look!

Re: Another BASIC noob question (DIM)

Posted: Wed Jan 04, 2023 1:51 pm
by beanz
RST#08 wrote: Wed Jan 04, 2023 11:23 am If you want to use arrays (and there are very good reasons why you might want to do this), you might want to consider embedding the length of the string into each array item as a 'hidden' CODE byte.

You then use slicing, something that ZX BASIC makes very easy. It's perhaps easier to show this rather than explain! There is a good example of this technique on pages 130-131 of this book:

https://spectrumcomputing.co.uk/entry/2 ... X_Spectrum

The example provided constructs the string array and embedded length bytes using INPUT, but there is no reason why you couldn't use READ, DATA etc. to do this.

Hope this helps :D

P.S. First post here :dance but I previously did one or two posts on the 'old' WOS using the same username.
Thanks,

Yeah the way my program is setup I kind of need it to "work" as I need to reference Z$(1), Z$(2) etc later on and the loop sits within a loop...so just changing the 'value' of Z$ isn't going to work because then I wont be able to reference the various other 'values'. Sure I could set up each one individually but it just seemed there "should" be a way (in my noob mind) to do it with a simple dim statement.

Long story short it's a horse racing game...with 6 or 7 "race meetings" (those being the city names)...after each race (which is the same loop used for each race) it needs to report "Cheltenham" winners circle with the city of the current race in the ""....I've got this working with the dim statement but then want to center justify the city name which I was planning to do by doing something along the lines of:

Print at 2, a; z$(n)
print at 3, 10; " Winners Circle"

Where 'a' would be 32 minus the len of z$(n) /2

Again, pretty much a noob at this, I'm trying to recreate a game I wrote nearly 40yrs ago and haven't really done any basic programming since.

Re: Another BASIC noob question (DIM)

Posted: Wed Jan 04, 2023 2:05 pm
by AndyC
In almost every other dialect of BASIC you'd be able to, as they tend to use "jagged" arrays of strings where each can have its own length. Sinclair BASIC does not.

I don't know if someone ingenious could craft something into a user defined function, so you could do something like FN s$(z$(1)) instead, which would be close to what you want. UDFs are pretty limited though ...

Re: Another BASIC noob question (DIM)

Posted: Wed Jan 04, 2023 2:55 pm
by equinox
Depending on what you are doing, you don't necessarily need a string array. Why not just use a simple numeric array? Each number is the position of a horse name in the DATA list. Then you're only using a simple string variable, which can be any length and won't be cut short like a string array element.

Example:

Code: Select all

1 DIM a(5): FOR x=1 TO 5: LET a(x)=INT (RND*5)+1: NEXT x
2 FOR x=1 TO 5: RESTORE: FOR y=1 TO a(x): READ n$: NEXT y: PRINT n$: NEXT x
10 DATA "Alice", "Bob", "Chris", "Dave", "Eric"
Line 1 creates a numeric array a(1..5) where each a(x) is a random number between 1 and 5 (the number of names we have).
Line 2 loops through that array and prints the names.

Re: Another BASIC noob question (DIM)

Posted: Wed Jan 04, 2023 3:18 pm
by WhatHoSnorkers
I know it has been suggested here but sticking the length at the front of the string would work too.

Character gives you 1-9, and if you go with a non-printable CODE character, that's up to 255. You just have to stick it at the front of the DATA statements.

Re: Another BASIC noob question (DIM)

Posted: Wed Jan 04, 2023 3:37 pm
by beanz
equinox wrote: Wed Jan 04, 2023 2:55 pm Depending on what you are doing, you don't necessarily need a string array. Why not just use a simple numeric array? Each number is the position of a horse name in the DATA list. Then you're only using a simple string variable, which can be any length and won't be cut short like a string array element.

Example:

Code: Select all

1 DIM a(5): FOR x=1 TO 5: LET a(x)=INT (RND*5)+1: NEXT x
2 FOR x=1 TO 5: RESTORE: FOR y=1 TO a(x): READ n$: NEXT y: PRINT n$: NEXT x
10 DATA "Alice", "Bob", "Chris", "Dave", "Eric"
Line 1 creates a numeric array a(1..5) where each a(x) is a random number between 1 and 5 (the number of names we have).
Line 2 loops through that array and prints the names.
Hmm that might be a simple solution, thanks.

Re: Another BASIC noob question (DIM)

Posted: Mon Jan 09, 2023 8:02 pm
by IvanBasic
beanz wrote: Wed Jan 04, 2023 1:51 pm I was planning to do by doing something along the lines of:

Print at 2, a; z$(n)
print at 3, 10; " Winners Circle"

Where 'a' would be 32 minus the len of z$(n) /2
For this purpose, just add the needed spaces at the beginning of each city, and print all of them in the same column, this is
PRINT AT 2,11;z$(n).