Shop OBEX P1 Docs P2 Docs Learn Events
Strings — Parallax Forums

Strings

Dr_AculaDr_Acula Posts: 5,484
edited 2009-12-07 02:54 in Propeller 1
I've just spent a little time browsing through the object exchange, and there have been some great additions over the last 6 months! And I have found a nifty string library by Brandon Nimon (maybe there are others too - any pointers would be most appreciated). Brandon's code has for example:
    debug.str(           string("SubStr-demo starting at right end of string",13))
    debug.str(           string("STR.substr(string(´1234567890ABCDEFGHIJ´), -18, 7))",13,13))




Which prints a smaller string.

Is there a way of storing the values, rather than just printing them out?

eg in BASIC;
A$="Hello "
B$="World"
C$=A$+B$ rem store the new string in C$ before printing it
...
PRINT C$




I've written some string handling for Z80 assembly in the past and, at the simplest level strings are just arrays of ascii characters. So
1) Arrays need to be defined as variables to store space for them
2) Strings need to end in a specific character (CP/M used $, but that means you can't print $, but I think ascii &H00 is the standard)
3) Strings can be variable or fixed length. MBASIC used variable length which saved space but every 10 mins or so, an MBASIC program would hang while it sorted out its strings. Fixed length makes more sense, and SBASIC used 32 bytes which seems to work well.

So my question really is, how do you go about defining space for strings before using them?

Is it a matter of declaring an array of 32 bytes (is that 8 LONGs?). Then filling those bytes with ascii zero so it is a blank string with zero length?

Then perhaps a subroutine where you pass it the name of that array and the bytes to fill it with. ie the equivalent of A$="Hello", something like 'definestring(stringname,"text") ' or 'fillstring'. Then passing the address of that array so you can manipulate it with string handling functions?

I see there is a STRING function in Spin but I'm not sure quite how to use it. Does it create the space for the string on the fly, or can you use it to permanently store strings somewhere? How would I go about writing the complete code in Spin for the following SBASIC code:
var mystring1 as string:32 rem reserve 32 bytes for mystring1, fill with null bytes
var mystring2 as string:32 rem reserve 32 bytes for mystring2, fill with null bytes
var mystring3 as string:32 rem reserve 32 bytes for mystring3, fill with null bytes
mystring1="Hello" rem put 5 bytes in mystring1 and terminate with a null byte
mystring2=" World" rem put 6 bytes in mystring2 and terminate with a null byte
mystring3=mystring1+mystring2 rem concatenate strings (possibly needs a function call rather than the implied function call in '+')
rem , eg str_concat(string1,string2,string3)
mystring3=left(mystring3,5) rem put the first 5 bytes in mystring3, terminate with a null and erase the rest of the bytes


▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/build

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2009-09-24 03:50
    The STRING function in Spin takes a string constant as a parameter, allocates storage for it and a zero terminator byte in the program (without checking for duplicates) and provides the address of the first byte. STRSIZE takes an address and returns the number of non-zero bytes before a zero byte. STRCOMP takes two addresses and compares the two strings at those addresses. It stops at the first zero byte and returns a TRUE / FALSE value for equality testing. BYTEFILL and BYTEMOVE can be used for string manipulation, but are not specifically intended for that in that they use length counts, not a zero byte terminator.

    As far as Spin is concerned, strings are just byte arrays that use a zero byte as a string terminator. If you want a 32 character string, you have to declare a 33 byte array and initialize the first byte to zero if you want an empty string.

    VAR byte mystring1[noparse][[/noparse] 33 ], mystring2[noparse][[/noparse] 33 ], mystring3[noparse][[/noparse] 33 ]
    PUB example
       bytefill(@mystring1,0,33)   ' Erase mystring1
       bytefill(@mystring2,0,33)   ' Erase mystring2
       bytefill(@mystring3,0,33)   ' Erase mystring3
       bytemove(@mystring1,string("Hello"),6)   ' Set mystring1 to "Hello".  Include zero terminator
       bytemove(@mystring2,string(" World"),7)   ' Set mystring2 to " World".  Include zero terminator
       catenate(@mystring3,@mystring1,@mystring2)   ' Set mystring3 to mystring1 + mystring2
       mystring3[noparse][[/noparse] 5 ] := 0   ' Put a terminator after first 5 characters of mystring3
    PUB catenate(answer,part1,part2) | length1
       length1 := strsize(part1)   ' Get length of first string
       bytemove(answer,part1,length1)   ' Copy first string to answer
       bytemove(answer+length1,part2,strsize(part2)+1)   ' Copy 2nd string to answer after 1st piece.  Also copy final zero byte
    ' Note that there's no checking for whether the catenated string still fits in the allocated space.
    
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2009-09-24 04:18
    Hi Mike,

    That is great. Many thanks - that makes a lot of sense and comes out almost the same number of lines. Now I can see a way to add some of the other string functions that I have in Z80 assembly - left(), right(), mid(), instr(), chr(), str(), hex() et al. This might be relevant for the various BASIC projects going on at the moment too. Cheers, James

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.smarthome.viviti.com/build
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2009-09-24 17:35
    The intention for most of the methods in the Strings library are for the strings to be moved to a permanent location with bytemove. Mike Green's advice is never bad either.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    April, 2008: when I discovered the answers to all my micro-computational-botherations!
  • w8anw8an Posts: 176
    edited 2009-12-06 20:37
    Curious, Mike, why do you need the three bytefill commands to erase the strings before moving text into them?

    Steve
  • Mike GreenMike Green Posts: 23,101
    edited 2009-12-06 20:55
    @w8an - I was just trying to copy Dr_Acula's Basic program. That program specified that the strings were erased.
  • w8anw8an Posts: 176
    edited 2009-12-07 01:20
    Ok, that makes sense. It didn't look like it would have any effect on the results, which is why I asked... Thanks.

    Steve
  • w8anw8an Posts: 176
    edited 2009-12-07 01:30
    I don't seem to have any luck with the syntax: bytemove(@destination_string, string("some text"), 10). If I don't use the "@" before destination_string, it appears to work. What am I missing here?

    Steve
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-12-07 02:25
    destination_string is probably already an address that points to the head of the string array. If so, you don't need the "@". Including it will only point to the variable that contains the string address, and that's not what you want.

    -Phil
  • w8anw8an Posts: 176
    edited 2009-12-07 02:54
    Ok. That's where my confusion arose then. The examples I found on the forum indicated usage of the @string, but looks like @pointer which doesn't make sense. I'm wondering if there are any detailed docs on usage of vars (specifically string arrays) out there in the cloud somewhere?
Sign In or Register to comment.