combining strings with SPIN
 TC            
            
                Posts: 1,019
TC            
            
                Posts: 1,019            
            
                    Hello all,
I have been trying for a couple hours to combine different strings and values, and make one string.
I used code from FullDuplexSerial to try and help, but it did not.
lets say I have in the DAT section,
And I have a decimal value of 5 (not ASCII "5")
What I want in one variable is
Here is the code I have made, that doe not work. Is there something I am doing wrong?
Thanks for any help
TC
                            I have been trying for a couple hours to combine different strings and values, and make one string.
I used code from FullDuplexSerial to try and help, but it did not.
lets say I have in the DAT section,
sen_num byte "SENSOR_", 0 file_format byte ".CSV", 0
And I have a decimal value of 5 (not ASCII "5")
What I want in one variable is
"SENSOR_5.CSV"
Here is the code I have made, that doe not work. Is there something I am doing wrong?
PUB
  New_File(@sen_num, 5, @file_format)
PUB New_File(string_pointer, number, format) | string_temp, c, i
  repeat strsize(string_pointer)
    c := byte[string_pointer++]
    if c <> 0
        byte[string_temp++] := c
  i := 1_000_000_000                                    'Initialize divisor
  repeat 10                                             'Loop for 10 digits
    if number => i                                                               
      byte[string_temp++] := (number / i + "0")      'If non-zero digit, output digit; adjust for max negative
      number //= i                                      'and digit from value
      result~~                                          'flag non-zero found
    elseif result or i == 1
      byte[string_temp++] := "0"                                           'If zero digit (or only digit) output it
    i /= 10                                             'Update divisor
  repeat strsize(format)
    c := byte[format++]
    if c <> 0 
        byte[string_temp++] := c
  com.str(@string_temp)
  com.tx(13)
Thanks for any help
TC

 
                            
Comments
Thanks Dave, But I am not displaying this on the serial terminal. This is to make a new file on a SD-card(file name). That is why I need it to be a variable. I only have the last 2 lines to check my code. But I will try adding a 0 to it. That might be where I am screwing up.
byte[string_temp] := 0 com.str(string("File Name -- ")) com.str(string_temp) com.tx(13)and the prop will reboot when it hits
If I comment only that line, the prop will not reboot. There is nowhere in my code that tells the prop to reboot.
Can you post the entire code? My guess is "string_temp" has been set to zero so you're writing zero to the first byte of RAM which messes up the Prop's clock settings. I've cause resets this way many times myself.
I can, but it is really not that great. I still have a lot to do, I try to organised it when I can. Sorry about all the hacks. I'm working on 2 bugs now, one is this problem. The other one I am going to try to figure out if I can fix it first, before I ask for help.
repeat strsize(string_pointer) +1 'the "+1" is only there to see the null-terminator c := byte[string_pointer++] byte[out_string++] := c com.tx(13) com.dec(c) 'I get correct value on "c" com.tx(13) com.tx(13) com.tx(13) com.str(string("out string -- ")) com.str(out_string) com.tx(13) com.tx(13)I have tried different ways of doing " com.str(out_string) ". I have added the PRE-increment and POST-increment, i have tried the address symbol. And it will only show a few spaces and a "+".
I am at wits end..... Please tell me what am I missing.
Change the method "New_File" from:
pub New_File(string_pointer, number, format) | string_temp, c, i repeat strsize(string_pointer) c := byte[string_pointer++] if c <> 0 byte[string_temp++] := c if number <> -1 i := 1_000_000_000 'Initialize divisor repeat 10 'Loop for 10 digits if number => i byte[string_temp++] := (number / i + "0") 'If non-zero digit, output digit; adjust for max negative number //= i 'and digit from value result~~ 'flag non-zero found elseif result or i == 1 byte[string_temp++] := "0" 'If zero digit (or only digit) output it i /= 10 'Update divisor repeat strsize(format) c := byte[format++] if c <> 0 byte[string_temp++] := c byte[string_temp] := 0 ' com.str(string("File Name -- ")) ' com.str(string_temp) ' com.tx(13) Check_Master_File '***** TEMP for checking ***** return trueTo:
pub New_File(string_pointer, number, format) | string_temp[3], local_pointer, c, i local_pointer := @string_temp repeat strsize(string_pointer) c := byte[string_pointer++] if c ' same as if c <> 0 byte[local_pointer++] := c if number < 0 ' don't add number characters if number is -1 i := 1_000_000_000 'Initialize divisor repeat 10 'Loop for 10 digits if number => i byte[local_pointer++] := (number / i + "0") 'If non-zero digit, output digit; adjust for max negative number //= i 'and digit from value result~~ 'flag non-zero found elseif result or i == 1 byte[local_pointer++] := "0" 'If zero digit (or only digit) output it i /= 10 'Update divisor repeat strsize(format) c := byte[format++] if c byte[local_pointer++] := c byte[local_pointer] := 0 ' com.str(string("File Name -- ")) ' com.str(@string_temp) ' com.tx(13) Check_Master_File '***** TEMP for checking ***** return trueYou should be able to uncomment the section below without crashing your program:
' com.str(string("File Name -- ")) ' com.str(@string_temp) ' com.tx(13)Rather than just checking or -1, the method will ignore any negative number since negative numbers will not work correctly in your algorithm.
Duane.... YOU ARE AMAZING!! I've been trying for a couple hours to figure out what I was doing wrong. Thank you so much.
I had to change it to
Your way worked, but it would still place a "0" in line. I wanted it so that if I place a "-1", it would skip loading a number. Trying to combine code where I can, and make things a little more efficient.
Again. Thank you so much.
TC
1) look out using a variable as a buffer AND a pointer. Could be a problem later
2) I did not know why others did but now I know.
Thank you
Sorry, I had the inequality sign backwards and I forgot the "or equal" part.
It should have been:
I think using your "ifnot" with my original "< 0" would also work.
This way it would skip any negative number not just negative one. A negative number would not be processed correctly by the algorithm.
You're very welcome.
Now it's a simple matter of changing that character.
Okay, so you say you want to change the extension of the file name? That's easy too -- here's a little method that lets you set the sensor number and file type
pub set_filename(sn, ftype) FileName[7] := sn + "0" if (ftype == 0) bytemove(@Filename[8], string(".csv"), 5) elseif (ftype == 1) bytemove(@Filename[8], string(".wav"), 5) else bytemove(@Filename[8], string(".err"), 5)We use 5 with bytemove so that we copy the string (period plus three characters) AND the terminating zero -- this is necessary for string methods.
Here's an actual bit of code I wrote for my friend, Bob, who uses the AP-16+ (which I co-designed and coded) in fun little toys. His latest project will randomize one of a hundred files within one of eight groups. Press the group button, get a random file. Here's his dat section
And here's the code that updates FileName before playing the file.
pub make_filename(grp, fn) '' Updates embedded string with file number '' -- gn is the group # '' -- fn is the file number (00..99) FileName[5] := "0" + grp FileName[6] := "0" + fn / 10 FileName[7] := "0" + fn // 10DAT filename byte "LOG-xxxx.txt" PUB Record(counter) | t, i, m, div, value div := 1000 value := word[counter] '... i := 4 repeat 4 if value => div filename[i++] := (value / div + "0") value //= div else filename[i++] := "0" div /= 10 '... \sd.popen(@filename,"w")It doesn't combine strings, rather it overwrites part of the existing string. I fixed the length to four digits as I doubt I'll exceed 10000 recordings.If the period and terminator already exist in the target string, it's enough just to bytemove the three-character extension ... right?
-Phil
That is great Jon, I will give it a shot. It is definitely a lot smaller in size, and easier to read.
TC: Given the dat section I suggested, this line would work:
bytemove(@Filename[9], string("csv"), 3)ASCII0_STREngine.spin
It is probably in the OBEX.