Picking out characters from a string
in Propeller 1
I'm trying to display individual words from a string.
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
OBJ
pst : "Parallax Serial Terminal"
var
long value, x
Pub Main
pst.Start(115_200)
waitcnt(clkfreq * 2 + cnt)
pst.Clear
pst.Str(String("press any key"))
value := pst.CharIn
pst.Chars(pst#NL,1)
x:=1
repeat while x < 16
pst.Char(@three[x])
x++
pst.Char(@three[x])
x++
pst.Char(@three[x])
x++
pst.Chars(pst#NL,1)
pst.Chars(pst#NL,1)
pst.Str(String("done"))
repeat
Dat
'Three letter words
Three byte "theandforarebutnotyouallanycanherwasoneouroutday",0
Comments
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 OBJ pst : "Parallax Serial Terminal" var long value, x Pub Main pst.Start(115_200) waitcnt(clkfreq * 2 + cnt) pst.Clear pst.Str(String("press any key")) value := pst.CharIn pst.Chars(pst#NL,1) x:=0 repeat while three[x] <> 0 pst.Char(three[x]) x++ pst.Char(three[x]) x++ pst.Char(three[x]) x++ pst.Chars(pst#NL,1) pst.Chars(pst#NL,1) pst.Str(String("done")) repeat Dat 'Three letter words Three byte "theandforarebutnotyouallanycanherwasoneouroutday",0
Changes are:
* Reference the variable 'Three' directly, instead of its address
* The index 'x' is initialized with 0 (that's the first element of your variable 'Three' - it started with 1 before, which would be the 'h' in the word 'the')
* The repeat block now loops as long as the value of three isn't 0/NUL (which was used but not tested for in your original example)
Cheers,
Jesse
pub sub_string(p_dest, p_src, ofs, len) '' Copy sub-string from p_src to p_dest '' -- ofs is offset of len-lenthed sub-string ofs *= len ' convert word offset to 1st char position bytemove(p_dest, p_src+ofs, len) ' copy len characters byte[p_dest+3] := 0 ' 0-terminate destination string return p_dest
I tested with this snippet and it works fine. Note that I use my own version of FDS, not PST.
repeat idx from 0 to 15 term.dec(idx) term.tx(term#TAB) term.str(sub_string(@buffer, @Words3, idx, 3)) term.tx(13)
pub sub_string(p_dest, p_src, ofs, len) '' Copy sub-string from p_src to p_dest '' -- ofs is offset of len-lenthed sub-string ofs *= len ' convert word offset to 1st char position bytemove(p_dest, p_src+ofs, len) ' copy len characters byte[p_dest+len] := 0 ' 0-terminate destination string (FIXED) return p_dest
BTW, when you see repeated code in your listing you can use condense it with... repeat. For example, from your original listing you could do this:
repeat 3 pst.Char(@three[x++])
Is this the one?
http://obex.parallax.com/object/579
You guys are the best!
repeat value := pst.CharIn if value == 49 '#1 three letter words LetterCount:=3 wordmove(@TestWords,@three, 198) 'Copy three to TestWords ManyWords:=66 ' How many words quit if value == 50 '#2 four letter words LetterCount:=4 wordmove(@TestWords,@four, 280) 'Copy four to TestWords ManyWords:=70 quit
In another subroutine I extract random words from TestWords. If I extract directly from three or four the words line up correctly.I fixed it by subtracting 1 from the extraction index. I just want to know why I needed to do this.
here is the word extraction subroutine
x:= random * LetterCount w:=0 x:=X-1 repeat while x < (LetterCount * random + LetterCount)-1 TheWord[w]:=TestWords[x] x++ w++
Thanks.
You were right, thanks.
bytemove(@TestWords, @three, strsize(@three)+1)
Two things: 1) Use bytemove, not wordmove, and 2) Use strsize() so that you don't have to count the length of the string -- this will let you update the string without having to go back in and fix the code. The reason for the +1 is that it will copy the terminating 0 from the source to the destination.Yes, that's it.
Kye has a very nice way of commenting his code, especially tuned for beginners.
To me, the names of the routines and variables are quite long, but they do exactly what the name says.