Shop OBEX P1 Docs P2 Docs Learn Events
Copy a part of a string to a new string ? — Parallax Forums

Copy a part of a string to a new string ?

nestor73nestor73 Posts: 33
edited 2011-06-20 12:00 in Propeller 1
I have learned the SPIN language for almost 2 weeks now, and i have to say that,
even do i'm a programmer for over 20 years, this language is the worst i've writtin
in ! This is not to be called a 'high-level' language at all. Or maybe i'm getting very
frustrated that i can't even seem to get the easiest thing done like,

1) adding 2 strings to eachother ?
2) I need to be able to copy a part of a string . In my case , the string contains a 2 digit
number and i need to be able to put the first one in a new string, and the second one too..

Is there an 'easy' way to do this ? i haven't been able to come up with something that
at least works a bit :frown:

Comments

  • StefanL38StefanL38 Posts: 2,292
    edited 2011-06-19 11:46
    call SPIN a low-level-language if you like. Maybe looking onto it as a limited low-level language makes it easier to use.
    Because then you don't expect big things like variable datarecords. You got bytes words longs. That's it.
    For more complex things you the user have to care about all the details.

    Strings are defined as byte-arrays where each byte contains one ascii-coded character.
       byte MyStr[16]
    
    copying a complete byte-array can be done with the command bytemove. If you want to copy parts of a string you have to calculate offsets
    another possability is to copy it bytewise
       byte MyStrA[16]
       byte MyStrB[16]
    
      MyStrB[0] :=  MyStrA[4]
      MyStrB[1] :=  MyStrA[5]
    etc.
    
    there are some string-handling objects in the obex

    http://obex.parallax.com/objects/543/

    keep the questions coming
    best regards

    Stefan
  • Mike GreenMike Green Posts: 23,101
    edited 2011-06-19 11:55
    Usually BYTEMOVE is used to move characters around from string to string. Look at the description of it in the Propeller Manual. You need to know how many characters you're moving and the BYTEMOVE doesn't do anything about the end of string marker (a zero byte). You have to allow for that yourself.
  • Mike GMike G Posts: 2,702
    edited 2011-06-19 12:52
    1) adding 2 strings to eachother ?
    Concatenate? Like Mike and StefanL38 explained, you have to move the strings yourself. It's similar to C without using the <string> library where strings are char arrays. You can find string objects in the OBEX.
    2) I need to be able to copy a part of a string . In my case , the string contains a 2 digit
    Are the two digits integers or ASCII? If they are integers you have to ASCII encode the numbers before concatenating to the end of a string. This is consistent with any high level language although subtle; ie obejct.ToString()
    CON
      _clkmode = xtal1 + pll16x     
      _xinfreq = 5_000_000
      
      BUFF_LEN      = 64
    
    DAT
      str1  byte  "Hello ",0
      str2  byte  "World",0
      num   byte  1
      buff  byte  $0[BUFF_LEN]
    
    OBJ
      pst           : "Parallax Serial Terminal.spin"
    
    PUB Main | ptr
      'Start Parallax Serial Terminal
      pst.Start(115_200)
      pause(200)
    
      'Clear string buffer
      bytefill(@buff, 0, BUFF_LEN)
    
      'Display str1 and str2
      pst.str(@str1)
      pst.char(13)
      pst.str(@str2)
      pst.char(13)
      pst.str(string(13, "Concatenate str1 and str2", 13))
    
      'Concatenate str1 and str2
      'buff pointer
      ptr := @buff
      'move str1 into buff
      bytemove(ptr, @str1, strsize(@str1))
      'update pointer
      ptr += strsize(@str1)
      'Append str2 to the end
      bytemove(ptr, @str2, strsize(@str2))
      ptr += strsize(@str2)
    
      'Display result
      pst.str(@buff)
      pst.char(13)
    
      'Convert number 1 to ASCII character
      
      pst.str(string("Print ASCII "))
      pst.dec(num)
      pst.str(string(": "))
      num := num + $30  
      pst.char(num)
      pst.char(13) 
    
    
    PRI Pause(Duration)  
      waitcnt(((clkfreq / 1_000 * Duration - 3932) #> 381) + cnt)
      return
    
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-06-19 13:28
    Nestor, I don't think that SPIN is as bad as you say! Maybe you're mixing up the terms programming language and library. SPIN is very much like C, it only gives you a limited number of 'native' instructions/operators. For the complex things you need a library called objects in SPIN-world. Hence, in C or Java or many other languages the string-functions are functions as well - and not native instructions.

    Maybe you could even solve the problem beforehand! Do you really need to copy, or could you propably put the numbers to the right position in the first place?

    Post your code and we can help you to improve your SPIN skills.
  • nestor73nestor73 Posts: 33
    edited 2011-06-20 02:10
    Thanks all !!


    It's highly possible that i'm so new to this, and i'm so used to progamming in PHP and Pascal that i'm so distant from this way of working. But i did program for the arduino last year and that worked just allot easier. For some reason the SPIN tool is hard for me to see trough, dunno.

    Anyway, i found a function called SubStr in an object called 'strings'. I ripped it out of it, i'm already low on programming space so i don't need all the other functions that it's bringing . And that works fine.

    I did work my way around the concatenate of the strings by working with a buffer and returning that from the function. Works also ok. But it's only a matter of time before i bump into a new problem. ha. I don't have my code here in this computer since i work on another one for that, i'll upload code from there later.

    The problem that i'll run into will be screen slowness. I have build a big clock out of characters, meaning that for example the "0" is made out of a series of empty (red colored) strings that are positioned in a way that it created a half screen size (vga) character. Because i have two clocks (timers) on screen it will take a hell of a time to update 8 big characters
    An example of that screen can be seen here ::
    IMAG0041.jpg


    This screen is just showing fixed characters, but last night i've been working to make them running,
    and experienced allot of slowness. I'll make it that way that only the characters that are changing are
    updating, but still i don't expect it to go smooth :(.

    Anyone has a better idea to get those big clocks smooth onscreen ?
    1024 x 613 - 74K
  • nestor73nestor73 Posts: 33
    edited 2011-06-20 07:26
    Here is the SubStr routine :
    PUB SubStr (strAddr, start, count) | size
     
    {{Returns part of a string for count bytes starting from start byte.
    NOTE: forward counting starts at 0.
    example: char-position 01234567890
    string:                ABCDEFGHIJK
    SubStr("ABCDEFGHIJK",-4,2)
    Output: "HI"
    }}
     
      size := strsize(strAddr)
      IF (start < 0)                                                                ' if value is negative, go to the end of the string
        start := size + start
      IF (count < 0)                                                                ' if value is negative, go to the end of the string
        count := (size + count - start) <# constant(STR_MAX_LENGTH - 1)
      ELSE
        count <#= constant(STR_MAX_LENGTH - 1)
     
      bytemove(@ostr, strAddr + start, count)                                       ' just move the selected section
      ostr[count] := 0                                                              ' terminate string
      RETURN @ostr
    
  • JonnyMacJonnyMac Posts: 9,208
    edited 2011-06-20 07:31
    Here's a version I came up with yesterday -- you had an answer before I posted it. It's very much the same as yours though I simplified the dealing with the substring length using the max (<#) operator. I don't deal with negative length or position values because, in practice, these can be very confusing (when others are reading our code).

    You have to pass two string addresses (the destination and the source) along with the start position (inside the source) and the length of the substring. The method returns the destination pointer passed to it so that you can embed this method inside .str() methods.
    pub substr(dest, src, start, len)
    
    '' Copies len characters from src string, beginning at 'start'
    
      len <#= strsize(src)-start                                    ' limit to available chars
    
      bytemove(dest, src+start, len)                                ' copy characters
      byte[dest][len] := 0                                          ' terminate new string
    
      return dest                                                   ' return destination
    

    Example:
    term.str(substr(@buffer, string("Parallax Propeller"), 9, 9))
    

    ...will print "Propeller" to the terminal. The array called buffer holds the result.
  • nestor73nestor73 Posts: 33
    edited 2011-06-20 09:03
    Thanks, But i seem to be still very struggling with this language

    hope to get the code to display those big characters working and put it here for others to use
  • StefanL38StefanL38 Posts: 2,292
    edited 2011-06-20 12:00
    If you attach your code to a posting the forum-members can examine the code and make suggestions.
    keep the questions coming
    best regards

    Stefan
Sign In or Register to comment.