Shop OBEX P1 Docs P2 Docs Learn Events
string + string, combining string — Parallax Forums

string + string, combining string

courtenscourtens Posts: 101
edited 2012-03-14 08:20 in Propeller 1
Is there an way to do this; to combine two strings
string("hello " + "world")

Thanks

...

Sorry - I just solved it
string("hello " , "world")

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2012-03-01 11:47
    That works for string constants, but won't work for strings that vary. You would declare a byte array that's large enough to hold the largest string that you're going to use, then use STRSIZE and BYTEMOVE to move the pieces around (and account for the zero byte at the end of the string value). For example:
    VAR BYTE string1[256]
    
    bytemove(@string1, string("hello "), 7)   ' move the 6 characters and a final zero byte
    
    bytemove(@string1+6, string("world"), 6)   ' move the last 5 characters and a zero byte overwriting the previous zero byte
    
    ' you could also do this if you don't know how big the current string is:
    
    bytemove(@string1 + strsize(@string1), string("world"), 6)
    
  • Heater.Heater. Posts: 21,230
    edited 2012-03-02 03:05
    courtens

    Actually it's weird what this does in Spin,
    "hello " + "world"
    

    These strings are treated as bytes and the "+" operator adds the numeric value of 'o' to that of 'w' then sticks that result in the middle producing a rather unexpected string result.
  • courtenscourtens Posts: 101
    edited 2012-03-13 13:33
    Thanks Mike!

    I finally got it to work, but only after trying to call for the value by using the @

    this works:
    tv.str(@string1)

    this will give some funny stuff back
    tv.str(string1)

    Mike, your code helped me digest the log post Bytemove-question,

    Now I need to add a number to my "hello world", would I first need to convert the number into a sting with the numbers.spin function FromStr(StrAddr, Format)?
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-03-13 13:39
    courtens wrote: »
    Now I need to add a number to my "hello world", would I first need to convert the number into a sting with the numbers.spin function FromStr(StrAddr, Format)?

    I know there's a thread about how to do this.

    I think Larry (Lardom) started the thread. I'll see if I can find it.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-03-13 13:54
    I couldn't find the thread I was thinking of.

    This isn't a complete demo but hopefully there's enough here that you can make sense of it.

    The code inserts four ASCII characters that represent the value held by the variable "tryCount" to the byte arrays "logName" and "backupName". The characters replace the original "0" characters. The idea was to have the file names increment each time a new file was created.

    The code is from a data logging project.
    LongToDecStr(++tryCount, 4, @logName + 4)   
      LongToDecStr(tryCount, 4, @backupName + 4)
    
    PUB LongToDecStr(value, digits, localPtr) | temp
    '' Write an ASCII decimal number to localPtr
      temp := 1
      repeat digits
        temp *= 10
      value //= temp                ' tuncate value that wont fit in digits
      repeat digits
        temp /= 10
        byte[localPtr++] := (value / temp) + "0"
        value //= temp
    DAT
    
    logName       byte "WALK0000.TXT", 0
    backupName    byte "BACK0000.TXT", 0
        
    
  • courtenscourtens Posts: 101
    edited 2012-03-13 14:15
    Thank you Duane, -- for trying to find that post and for you code!

    I actually just got this this code to work using the numbers.spin function ToStr
    [FONT=courier new]var1 := 12345
    string3 := (n.ToStr(var1, n#DEC))[/FONT]
    [FONT=courier new]bytemove(@string1, string("hello "), 7)   ' move the 6 characters and a final zero byte
    bytemove(@string1+6, string3, 6)[/FONT]
    

    This gives me "hello 12345"
  • courtenscourtens Posts: 101
    edited 2012-03-13 18:44
    I am now stuck trying to add a new-line /nl (13) to the very end of my string

    This works if I send the sting out:

    _newLine:=13
    reg_25:=string("@16 11 25 965401272 ", _newLine)

    But anything else I am trying is a no go.
  • Mike GreenMike Green Posts: 23,101
    edited 2012-03-13 18:50
    What you've written won't work. STRING() only allows constants and constant expressions. You could write STRING("@16 11 25 965401272 ",13) and that will include a newline character in the string. Other than that, you have to build the string section by section in a buffer as you showed in the previous posting including a newline character at the end before any terminating zero byte. In that example, you could add: bytemove(@string1+11, string(13), 2)
    This would overwrite the final zero byte with two bytes ... the newline and a new zero byte at the end.
  • courtenscourtens Posts: 101
    edited 2012-03-13 19:23
    Thanks Mike!

    I just got it to work with using
    string3 := string(" ", _newLine, "test >>>")

    I had to increase the cog size and fix a typo in my code...
    if play==1                                                                                                                         
      string1 := string("@16 11 25")
    elseif rewind==1
      SVU_new := 0 - SVU_new                                                                                                                                    
      string1 := string("@16 11 25 ")
                             
    string1size := string1size0 := strsize(string1)
    string1size0 += 1                                                                                                                      
    string2 := (n.ToStr(SVU_new, n#DEC))
    string2size := string2size0 := strsize(string2)
    string2size0 += 1                                                                                                                            
    string3 := string(" ", _newLine, "test >>>") 
    string3size := string3size0 := strsize(string3)   
    string3size0 += 1
                                                                                                                                                                                   
    bytemove(@arr_25, string1, string1size0)                                                                                               
    bytemove(@arr_25 + string1size, string2, string2size0)                  
    bytemove(@arr_25 + string1size + string2size, string3, string3size0)
    
  • Mike GreenMike Green Posts: 23,101
    edited 2012-03-13 19:44
    I can believe your code will work if _newLine is defined as a constant (CON _newLine = 13), but not if it's a variable as shown in your post #8. The compiler should report an error if you've defined _newLine as a variable.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2012-03-14 02:12
    Have you seen Kye's string driver?

    There are functions to join strings, and a nifty one to build a string that can handle the backspace, so you can use it for a keyboard.
    {{
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // ASCII0 String Engine
    //
    // Author: Kwabena W. Agyeman
    // Updated: 8/28/2010
    // Designed For: P8X32A
    // Version: 1.2
    //
    // Copyright (c) 2010 Kwabena W. Agyeman
    // See end of file for terms of use.
    //
    // Update History:
    //
    // v1.0 - Original release - 4/10/2009.
    // v1.1 - Made code faster - 8/18/2009.
    // v1.2 - Updated library functions, fixed bugs, and made code more robust against whitespace and capitalization - 7/27/2010.
    //
    // For each included copy of this object only one spin interpreter should access it at a time.
    //
    // Nyamekye,
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    }}
    
    VAR
    
      word tokenStringPointer
      byte decimalString[12], hexadecimalString[9], binaryString[33], characterToStringPointer, characterToString[255]
    
    PUB buildString(character) '' 4 Stack longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Builds a string from individual characters. Use "builtString" to get the address of the string.
    '' //
    '' // If the backspace character is put into the string it is automatically evaluated by removing the previous character.
    '' //
    '' // If 254 characters are put into the string all characters excluding backspace that are put into the string are ignored.
    '' //
    '' // Character - The next character to include in the string. Null will be ignored.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      ifnot(characterToStringPointer)
        bytefill(@characterToString, 0, 255)
    
      if(characterToStringPointer and (character == 8))
        characterToString[--characterToStringPointer] := 0
    
      elseif(character and (characterToStringPointer <> 254))
        characterToString[characterToStringPointer++] := character
    
    PUB builtString(resetString) '' 4 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Returns the pointer to the string built from individual characters.
    '' //
    '' // Reset - If true the next call to "buildString" will begin building a new string and the old string will be destroyed.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      characterToStringPointer &= not(resetString)
      return @characterToString
    
    PUB builderNumber '' 3 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Returns the number of characters in the string builder buffer.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      return characterToStringPointer
    
    PUB builderFull '' 3 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Returns true if the string builder buffer is full and false if not.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      return (characterToStringPointer == 254)
    
    PUB stringCompareCS(characters, otherCharacters) '' 5 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Compares two strings case sensitively.
    '' //
    '' // Returns zero if the two strings are equal.
    '' // Returns a positive value if "characters" comes lexicographically after "otherCharacters".
    '' // Returns a negative value if "characters" comes lexicographically before "otherCharacters".
    '' //
    '' // Characters - A pointer to a string of characters.
    '' // OtherCharacters - A pointer to another string of characters.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      repeat
        result := (byte[characters] - byte[otherCharacters++])
      while(byte[characters++] and (not(result)))
    
    PUB stringCompareCI(characters, otherCharacters) '' 9 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Compares two strings case insensitively.
    '' //
    '' // Returns zero if the two strings are equal.
    '' // Returns a positive value if "characters" comes lexicographically after "otherCharacters".
    '' // Returns a negative value if "characters" comes lexicographically before "otherCharacters".
    '' //
    '' // Characters - A pointer to a string of characters.
    '' // OtherCharacters - A pointer to another string of characters.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      repeat
        result := (ignoreCase(byte[characters]) - ignoreCase(byte[otherCharacters++]))
      while(byte[characters++] and (not(result)))
    
    PUB stringCopy(whereToPut, whereToGet) '' 5 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Copies a string from one location to another. This method can corrupt memory.
    '' //
    '' // Returns a pointer to the new string.
    '' //
    '' // WhereToPut - Address of where to put the copied string.
    '' // WhereToGet - Address of where to get the string to copy.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      bytemove(whereToPut, whereToGet, (strsize(whereToGet) + 1))
      return whereToPut
    
    PUB stringConcatenate(whereToPut, whereToGet) '' 5 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Concatenates a string onto the end of another. This method can corrupt memory.
    '' //
    '' // Returns a pointer to the new string.
    '' //
    '' // WhereToPut - Address of the string to concatenate a string to.
    '' // WhereToGet - Address of where to get the string to concatenate.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      bytemove((whereToPut + strsize(whereToPut)), whereToGet, (strsize(whereToGet) + 1))
      return whereToPut
    
    PUB stringToLowerCase(characters) '' 4 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Demotes all upper case characters in the set of ("A","Z") to their lower case equivalents.
    '' //
    '' // Characters - A pointer to a string of characters to convert to lowercase.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      repeat strsize(characters--)
        result := byte[++characters]
        if((result => "A") and (result =< "Z"))
          byte[characters] := (result + 32)
    
    PUB stringToUpperCase(characters) '' 4 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Promotes all lower case characters in the set of ("a","z") to their upper case equivalents.
    '' //
    '' // Characters - A pointer to a string of characters to convert to uppercase.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      repeat strsize(characters--)
        result := byte[++characters]
        if((result => "a") and (result =< "z"))
          byte[characters] := (result - 32)
    
    PUB trimString(characters) '' 8 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Removes white space and new lines arround the outside of string of characters.
    '' //
    '' // Returns a pointer to the trimmed string of characters.
    '' //
    '' // Characters - A pointer to a string of characters to be trimmed.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      result := ignoreSpace(characters)
      characters := (result + ((strsize(result) - 1) #> 0))
    
      repeat
        case byte[characters]
          8 .. 13, 32, 127: byte[characters--] := 0
          other: quit
    
    PUB tokenizeString(characters) '' 8 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Removes white space and new lines arround the inside of a string of characters.
    '' //
    '' // Returns a pointer to the tokenized string of characters, or an empty string when out of tokenized strings of characters.
    '' //
    '' // Characters - A pointer to a string of characters to be tokenized, or null to continue tokenizing a string of characters.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      if(characters)
        tokenStringPointer := characters
    
      result := tokenStringPointer := ignoreSpace(tokenStringPointer)
    
      repeat while(byte[tokenStringPointer])
        case byte[tokenStringPointer++]
          8 .. 13, 32, 127:
            byte[tokenStringPointer - 1] := 0
            quit
    
    PUB findCharacter(stringToSearch, characterToFind) '' 5 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Searches a string of characters for the first occurence of the specified character.
    '' //
    '' // Returns the address of that character if found and zero if not found.
    '' //
    '' // StringToSearch - A pointer to the string of characters to search.
    '' // CharacterToFind - The character to find in the string of characters to search.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      repeat strsize(stringToSearch--)
        if(byte[++stringToSearch] == characterToFind)
          return stringToSearch
    
    PUB replaceCharacter(stringToSearch, characterToReplace, characterToReplaceWith) '' 11 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Replaces the first occurence of the specified character in a string of characters with another character.
    '' //
    '' // Returns the address of the next character after the character replaced on success and zero on failure.
    '' //
    '' // StringToSearch - A pointer to the string of characters to search.
    '' // CharacterToReplace - The character to find in the string of characters to search.
    '' // CharacterToReplaceWith - The character to replace the character found in the string of characters to search.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      result := findCharacter(stringToSearch, characterToReplace)
      if(result)
        byte[result++] := characterToReplaceWith
    
    PUB replaceAllCharacters(stringToSearch, characterToReplace, characterToReplaceWith) '' 17 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Replaces all occurences of the specified character in a string of characters with another character.
    '' //
    '' // StringToSearch - A pointer to the string of characters to search.
    '' // CharacterToReplace - The character to find in the string of characters to search.
    '' // CharacterToReplaceWith - The character to replace the character found in the string of characters to search.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      repeat while(stringToSearch)
        stringToSearch := replaceCharacter(stringToSearch, characterToReplace, characterToReplaceWith)
    
    PUB findString(stringToSearch, stringToFind) | index, size '' 7 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Searches a string of characters for the first occurence of the specified string of characters.
    '' //
    '' // Returns the address of that string of characters if found and zero if not found.
    '' //
    '' // StringToSearch - A pointer to the string of characters to search.
    '' // StringToFind - A pointer to the string of characters to find in the string of characters to search.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      size := strsize(stringToFind)
      if(size--)
    
        repeat strsize(stringToSearch--)
          if(byte[++stringToSearch] == byte[stringToFind])
    
            repeat index from 0 to size
              if(byte[stringToSearch][index] <> byte[stringToFind][index])
                result := true
                quit
    
            ifnot(result~)
              return stringToSearch
    
    PUB replaceString(stringToSearch, stringToReplace, stringToReplaceWith) '' 13 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Replaces the first occurence of the specified string of characters in a string of characters with another string of
    '' // characters. Will not enlarge or shrink a string of characters.
    '' //
    '' // Returns the address of the next character after the string of characters replaced on success and zero on failure.
    '' //
    '' // StringToSearch - A pointer to the string of characters to search.
    '' // StringToReplace - A pointer to the string of characters to find in the string of characters to search.
    '' // StringToReplaceWith - A pointer to the string of characters that will replace the string of characters found in the
    '' //                       string of characters to search.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      result := findString(stringToSearch, stringToReplace)
      if(result)
    
        repeat (strsize(stringToReplaceWith) <# strsize(stringToReplace))
          byte[result++] := byte[stringToReplaceWith++]
    
    PUB replaceAllStrings(stringToSearch, stringToReplace, stringToReplaceWith) '' 19 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Replaces all occurences of the specified string of characters in a string of characters with another string of
    '' // characters. Will not enlarge or shrink a string of characters.
    '' //
    '' // StringToSearch - A pointer to the string of characters to search.
    '' // StringToReplace - A pointer to the string of characters to find in the string of characters to search.
    '' // StringToReplaceWith - A pointer to the string of characters that will replace the string of characters found in the
    '' //                       string of characters to search.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      repeat while(stringToSearch)
        stringToSearch := replaceString(stringToSearch, stringToReplace, stringToReplaceWith)
    
    PUB integerToDecimal(number, length) '' 5 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Converts an integer number to the decimal string of that number padded with zeros.
    '' //
    '' // Returns a pointer to the converted string.
    '' //
    '' // Number - A 32 bit signed integer number to be converted to a string.
    '' // Length - The length of the converted string, "+" or "-" will be concatenated onto the head of converted string.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      length := (10 - ((length <# 10) #> 0))
    
      decimalString := "+"
      if(number < 0)
        decimalString := "-"
    
      if(number == negx)
        bytemove(@decimalString, string("-2147483648KA"), 11)
    
      else
        repeat result from 10 to 1
          decimalString[result] := ((||(number // 10)) + "0")
          number /= 10
    
      decimalString[length] := decimalString
      return @decimalString[length]
    
    PUB integerToHexadecimal(number, length) '' 5 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Converts an integer number to the hexadecimal string of that number padded with zeros.
    '' //
    '' // Returns a pointer to the converted string.
    '' //
    '' // Number - A 32 bit signed integer number to be converted to a string.
    '' // Length - The length of the converted string, negative numbers need a length of 8 for sign extension.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      repeat result from 7 to 0
        hexadecimalString[result] := lookupz((number & $F): "0".."9", "A".."F")
        number >>= 4
    
      return @hexadecimalString[8 - ((length <# 8) #> 0)]
    
    PUB integerToBinary(number, length) '' 5 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Converts an integer number to the binary string of that number padded with zeros.
    '' //
    '' // Returns a pointer to the converted string.
    '' //
    '' // Number - A 32 bit signed integer number to be converted to a string.
    '' // Length - The length of the converted string, negative numbers need a length of 32 for sign extension.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      repeat result from 31 to 0
        binaryString[result] := ((number & 1) + "0")
        number >>= 1
    
      return @binaryString[32 - ((length <# 32) #> 0)]
    
    PUB decimalToInteger(characters) | sign '' 10 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Converts a decimal string into an integer number. Expects a string with only "+-0123456789" characters.
    '' //
    '' // If the string has a "-" sign as its leading character the converted integer returned will be negated.
    '' //
    '' // If the string has a "+" sign as its leading character the converted integer returned will not be negated.
    '' //
    '' // Returns the converted integer. By default the number returned is positive and the "+" sign is unnecessary.
    '' //
    '' // Characters - A pointer to the decimal string to convert. The number returned will be 2's complement compatible.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      characters := checkSign(ignoreSpace(characters), @sign)
    
      repeat (strsize(characters) <# 10)
        ifnot(checkDigit(characters, "0", "9"))
          quit
    
        result := ((result * 10) + (byte[characters++] & $F))
      result *= sign
    
    PUB hexadecimalToInteger(characters) | sign '' 10 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Converts a hexadecimal string into an integer number. Expects a string with only "+-0123456789ABCDEFabdcef" characters.
    '' //
    '' // If the string has a "-" sign as its leading character the converted integer returned will be negated.
    '' //
    '' // If the string has a "+" sign as its leading character the converted integer returned will not be negated.
    '' //
    '' // Returns the converted integer. By default the number returned is positive and the "+" sign is unnecessary.
    '' //
    '' // Characters - A pointer to the hexadecimal string to convert. The number returned will be 2's complement compatible.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      characters := checkSign(ignoreSpace(characters), @sign)
    
      repeat (strsize(characters) <# 8)
        ifnot(checkDigit(characters, "0", "9"))
          ifnot(checkDigit(characters, "A", "F") or checkDigit(characters, "a", "f"))
            quit
    
          result += $90_00_00_00
        result := ((result <- 4) + (byte[characters++] & $F))
      result *= sign
    
    PUB binaryToInteger(characters) | sign '' 10 Stack Longs
    
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Converts a binary string into an integer number. Expects a string with only "+-01" characters.
    '' //
    '' // If the string has a "-" sign as its leading character the converted integer returned will be negated.
    '' //
    '' // If the string has a "+" sign as its leading character the converted integer returned will not be negated.
    '' //
    '' // Returns the converted integer. By default the number returned is positive and the "+" sign is unnecessary.
    '' //
    '' // Characters - A pointer to the binary string to convert. The number returned will be 2's complement compatible.
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
      characters := checkSign(ignoreSpace(characters), @sign)
    
      repeat (strsize(characters) <# 32)
        ifnot(checkDigit(characters, "0", "1"))
          quit
    
        result := ((result << 1) + (byte[characters++] & 1))
      result *= sign
    
    PRI ignoreCase(character) ' 4 Stack Longs
    
      result := character
      if((character => "a") and (character =< "z"))
        result -= 32
    
    PRI ignoreSpace(characters) ' 4 Stack Longs
    
      result := characters
      repeat strsize(characters--)
        case byte[++characters]
          8 .. 13, 32, 127:
          other: return characters
    
    PRI checkSign(characters, signAddress) ' 5 Stack Longs
    
      if(byte[characters] == "-")
        result := -1
    
      if(byte[characters] == "+")
        result := 1
    
      long[signAddress] := (result + ((not(result)) & 1))
      return (characters + (||result))
    
    PRI checkDigit(characters, low, high) ' 5 Stack Longs
    
      result := byte[characters]
      return ((low =< result) and (result =< high))
    
    ' added commands J Moxham Jan 2010
    
    PUB endsWithString(stringToSearch, stringToFind) '' 12 Stack Longs
    
    '' &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
    '' &#9474; Checks if the string of characters ends with the specified characters.                                                   &#9474;
    '' &#9474;                                                                                                                          &#9474;
    '' &#9474; Returns true if yes and false if no.                                                                                     &#9474;
    '' &#9474;                                                                                                                          &#9474;
    '' &#9474; StringToSearch - A pointer to the string of characters to search.                                                        &#9474;                                                           
    '' &#9474; StringToFind - A pointer to the string of characters to find in the string of characters to search.                      &#9474;                                                                           
    '' &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
    
      return ((stringToSearch + strsize(stringToSearch) - strsize(stringToFind)) == findString(stringToSearch, stringToFind)) 
    
    PUB Left(Source, Destination,Number)   ' returns the left number of characters
       repeat Number
          byte[Destination] := byte[Source]
          Source++
          Destination++
       byte[Destination] :=0 ' add in the zero terminator
         
                                                                          
    PUB Len(Source) ' returns the length of the string
      return strsize(Source)
    
    PUB Mid(Source,Destination,Start,Number) ' returns strings starting at start with number characters
      Start-- ' so starts at the right position
      Source += Start ' position 1 is the first character
      repeat Number
        byte[Destination] := byte[Source]
        Source++
        Destination++
      byte[Destination] :=0 'add in the zero terminator  
    
    PUB Copy(Source,Destination) ' reverse order to stringcopy. Can also use to create strings eg copy(string("test"),@lineoftext1)
      bytemove(Destination, Source, (strsize(Source) + 1))
    
    PUB Str(Destination,Number) | n' convert a number to a string representation. Uses Basic syntax, ie leading character is a space if +ve, and is - if negative  
        n := number ' temp store for at the end when add the + or -
        Destination += 10 
        byte[Destination] := 0 ' terminator
        Destination--
        repeat result from 10 to 1
          byte[Destination] := ((||(number // 10)) + "0")
          number /= 10
          Destination--
    
        destination++    ' points to start again
    
        repeat while byte[destination] == "0"  ' while equal to zero remove this leading zero
          repeat result from 0 to 11 ' include the zero terminator as well
            bytemove(destination+result,destination+result+1,1)' shuffle to left
        repeat result from 11 to 1 
          bytemove(destination+result,destination+result-1,1) ' shuffle once to right - leading space or -
        byte[destination] :=" " ' leading space if positive. Can use trim to remove this
        if (n<0)
          byte[destination] := "-"
    
    PUB Stringfill(Destination, Number,AsciiValue)' fill string with a string, eg 3,65 is"AAA" and 2,32 is "  "
        bytefill(destination,AsciiValue,Number) ' same as Basic "string$" function and can also replicate space$ 
        byte[destination+number] :=0 ' zero terminator
    
    PUB Instr(Source,AsciiValue) | j ' find asciivalue in Source. Returns 0 if not found
        j := 0
        repeat result from 0 to strsize(Source)
          if byte[source+result] == AsciiValue
            j := result + 1 ' basic format where 1 is the last first character of a string
        return j    
    
    'PUB Val(Source)' basic string to decimal value only works for integers not floating point, see DecimalToInteger above        
    
    
    
    
    {{
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //                                                  TERMS OF USE: MIT License
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
    // files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
    // modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
    // Software is furnished to do so, subject to the following conditions:
    //
    // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
    // Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
    // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
    // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
    // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    }}
    
  • courtenscourtens Posts: 101
    edited 2012-03-14 08:20
    Mike, thank you for pointing this out -- yes, _newLine is defined as a constant. Good to know that it matters. I thought they were the same thing; variables and constants... apparently not!
    Mike Green wrote: »
    I can believe your code will work if _newLine is defined as a constant (CON _newLine = 13), but not if it's a variable as shown in your post #8. The compiler should report an error if you've defined _newLine as a variable.


    Dr_Acula, thank you for your suggestion of using Kye's string driver. At this point I have all I need in this string @arr_25. It covers all I require it to do. Now I can use some math and send this command string to a motor ... and it works!



    I was trying to find some documentation about this "simple" sort of string + number handling thing, but could not easily find it. There is very little in the help files, very little in the "Official Book", none in the "Unofficial Book", bits and pieces all over the forum (thank goodness) and some here: propeller.wikispaces.com.

    Thinking on the bit/byte level is a new concept for me, and it was only thanks to the very helpful support in this forum -- it all started to make sense. I spent days reading on how to get this to work ... adding a number to a string, and adding a string to a string. So, thank you all again!

    My next thing to add to my code is saving values through a power off cycle using extra external memory ... :smile:
Sign In or Register to comment.