Shop OBEX P1 Docs P2 Docs Learn Events
Unable to Parse variable into string array — Parallax Forums

Unable to Parse variable into string array

Dear forum,


I currently have a variable that I have to convert to string and split (parse) each value and store them in a byte array, so for example the value 8970, I have to store it as follows:


databuffer[0] = "8"
databuffer[1] = "9"
databuffer[2] = "7"
databuffer[3] = "0"


I am using the strings2.spin library, and wrote the following testing code:
CON

       
  _CLKMODE      = XTAL1 + PLL2X
  _XINFREQ      = 5_000_000               

OBJ

  DEBUG  : "FullDuplexSerial"
  STR    : "STRINGS2"

VAR


  byte  databuffer[100]  


PUB Main | strh

  DEBUG.start(31, 30, 0, 57600)
  waitcnt(clkfreq + cnt)  
  DEBUG.tx($0D)

'' Examples working fine, and displaying properly to the screen:

  DEBUG.str(STR.Parse(string("41410"),0,1))
  DEBUG.tx($0D)
  DEBUG.str(STR.Parse(string("78549"),1,1))
  DEBUG.tx($0D)
  DEBUG.str(STR.Parse(string("21784"),2,1))
  DEBUG.tx($0D)
  DEBUG.str(STR.Parse(string("29305"),3,1))
  DEBUG.tx($0D)
  DEBUG.str(STR.Parse(string("59204"),4,1))
  DEBUG.tx($0D)
  
'' Trying to save single digit to an element in the array: 
  databuffer[0] := STR.Parse(string("41410"),0,1)   ' It should save "4" into databuffer[0]
  databuffer[1] := STR.Parse(string("78549"),1,1)   ' It should save "8" into databuffer[1]
  databuffer[2] := STR.Parse(string("21784"),2,1)   ' It should save "7" into databuffer[2]
  databuffer[3] := STR.Parse(string("29305"),3,1)   ' It should save "0" into databuffer[3]
  databuffer[4] := STR.Parse(string("59204"),4,1)   ' It should save "4" into databuffer[4]


'' Up to this point, it seems to work ok (if it saved the values in the array elements),
'' but when I add the following part, I get weird results in the display:

'' Displaying stored values to screen:
  DEBUG.str(databuffer[0])
  DEBUG.tx($0D)
  DEBUG.str(databuffer[1])
  DEBUG.tx($0D)
  DEBUG.str(databuffer[2])
  DEBUG.tx($0D)
  DEBUG.str(databuffer[3])
  DEBUG.tx($0D)
  DEBUG.str(databuffer[4])
  DEBUG.tx($0D)

                  

So I noticed that it displays the correct values to the terminal, but I do not know if it saves them correctly to the array elements, because when I try to display them, I get random values. What am I doing wrong? Is there another object/method that I can use for this other than string2.spin?. I am attaching the entire project so you can review it.

Thank you very much

Comments

  • dgatelydgately Posts: 1,630
    edited 2016-08-20 18:38
    jmmb392 ,

    Lots of stuff going on under this simple-seeming code...

    The data type that you are using to contain your variables is not compatible with the way you are using it. Your buffer is basically an array of bytes. STR.Parse returns the address of a zero-terminated string that is also +1 the size of the length you requested. When you store that result into your buffer, you are not storing "4" into data buffer[0], but are storing either the address of the 'new' string or the string itself (I'm still trying to examine which) into databuffer[0], databuffer[1], databuffer[2], databuffer[3], etc...

    STR.Parse code looks like this:
    strAddr += start
      byte[strAddr + count] := 0                                                    ' terminate string
      RETURN strAddr
    

    Later in your code, we see:
    DEBUG.str(databuffer[0])
    
    DEBUG.str(...) expects the address of a string type... So, it does exactly as requested and tries to print a string starting at databuffer[0] and running until it finds a '0'.

    But, after stating all of the above as an explanation of the results you are getting, the real question is what is the problem your code is trying to solve? Do you want integer values in your databuffer array or ASCII character values? If you want integer values, the STRINGS2 library is not going to be your friend. If you want ASCII values, there are better ways, as well. Post an example of what you want the databuffer to contain (and its use) and you'll probably get some help.



    dgately
  • dgatelydgately Posts: 1,630
    edited 2016-08-20 19:25
    OK, I see that you said up-front that you wanted the character values to be stored in databuffer... Here's a simplified example (the STR.Parse code gave me a clue to this solution. See the getIndexedChar method):
    CON
           
      _CLKMODE      = XTAL1 + PLL2X
      _XINFREQ      = 5_000_000               
    
    OBJ
    
      DEBUG  : "FullDuplexSerial"
    
    VAR
    
      byte  databuffer[100]  
    
    PUB Main | strh
    
      DEBUG.start(31, 30, 0, 115200)
      waitcnt(clkfreq + cnt)
      DEBUG.tx($0D)
      
    '' Trying to save single digit to an element in the array: 
      databuffer[0] := getIndexedChar(string("41410"),0)   ' It should save "4" into databuffer[0]
      databuffer[1] := getIndexedChar(string("78549"),1)   ' It should save "8" into databuffer[1]
      databuffer[2] := getIndexedChar(string("21784"),2)   ' It should save "7" into databuffer[2]
      databuffer[3] := getIndexedChar(string("29305"),3)   ' It should save "0" into databuffer[3]
      databuffer[4] := getIndexedChar(string("59204"),4)   ' It should save "4" into databuffer[4]
    
    '' Displaying stored values to screen:
      DEBUG.tx(databuffer[0])                  ' databuffer[n] contains a single char value
      DEBUG.tx($0D)                                ' i.e. NOT a string
      DEBUG.tx(databuffer[1])
      DEBUG.tx($0D)
      DEBUG.tx(databuffer[2])
      DEBUG.tx($0D)
      DEBUG.tx(databuffer[3])
      DEBUG.tx($0D)
      DEBUG.tx(databuffer[4])
      DEBUG.tx($0D)
                 
    PRI getIndexedChar (strAddr, index)                 '  this method just returns the character value in the string as pointed to by index
     
      strAddr += index                          ' provides the address of the character to return
      RETURN byte[strAddr]                      ' return the byte value of the character
    
  • JonnyMacJonnyMac Posts: 9,104
    edited 2016-08-20 19:57
    A string requires at least two bytes: one byte for a character, another for the terminating zero. And for single characters, like the elements of your array, you should use the tx() method, not str() which is expecting a pointer to a z-string.

    Here's a simple method to pull an indexed character from a string:
    pub get_char(p_str, n)
    
    '' Returns nth character from str at p_str
    
      if (n < strsize(p_str))
        return byte[p_str][n]
      else
        return "?"
    
    Use this instead of the str.parse() method -- the parse() method is returning a pointer, not a character.
  • Yes, please be sure to use JonnyMac's get_char as it is much more safe than my less-than-cautious getIndexedChar!

    dgately
  • JonnyMac wrote: »
    A string requires at least two bytes: one byte for a character, another for the terminating zero. And for single characters, like the elements of your array, you should use the tx() method, not str() which is expecting a pointer to a z-string.

    Here's a simple method to pull an indexed character from a string:
    pub get_char(p_str, n)
    
    '' Returns nth character from str at p_str
    
      if (n < strsize(p_str))
        return byte[p_str][n]
      else
        return "?"
    
    Use this instead of the str.parse() method -- the parse() method is returning a pointer, not a character.
    dgately wrote: »
    Yes, please be sure to use JonnyMac's get_char as it is much more safe than my less-than-cautious getIndexedChar!

    dgately

    Thank you both for your suggestions, I followed your advises, and got the code to work!! Thank you JonnyMac and dgately!!
Sign In or Register to comment.