B4R Question String Concatenation

Starchild

Active Member
Licensed User
Longtime User
Just playing with the B4R development environment.
No hardware at this time.

The compiler rejects:
dim A as string
A = "123" & "456"

Error is "Concatenation operator not supported"

It does however accept:
A = "123" + "456"

Is this, string concatenation or mathematical addition of the numerical values?
ie. does A = "123456" or "579"
What if A was type LONG?
Do strings need to be concatenated as byte arrays (.GetBytes)?
Is there a StringBuilder?

Hopefully hardware will arrive soon and I will be able to do my own testing.
Just that I am looking at porting code into B4R and see this as a concern for me.
 

Starchild

Active Member
Licensed User
Longtime User
I am handling a packet protocol for passing data within an existing system between several different technologies, windows, apps and now micros too.
Encoding/Decoding packets, parsing values, checking and constructing reply packets.

I suppose I will need to drop the class approach and go back to a more basic memory mapped packet and dissection.
I will probably move to byte arrays to give me the flexibility needed.
I suppose it will end up a primitive String Builder (in concept) for assembling a new packet by reusing the same array over and over.

Anyway.
I have spent the last few days reviewing the B4R and the Supported Microcontrollers, boards and specialised imbedded chip solutions available now days.
Things certainly have evolved.

I have got to say I am excited about the possibilities B4R will offer.
Look forward to getting hardware running.

Thanks Erel.
 
Upvote 0

Starchild

Active Member
Licensed User
Longtime User
Good in theory.
Unfortunately, the entire packet must be created in order to add in the final part (mid packet).
I know it's odd.
I'll find another way.

Other languages (for micros) also have restrictions of managing strings.
Although it would be good to be able to declare a string variable to a known length and then be able to work within that declared length.
vb6 uses .. dim S as string[10] .. fixed length string of 10 chrs

Anyway, thanks again.
 
Upvote 0

inakigarm

Well-Known Member
Licensed User
Longtime User
I've searched a way to concatenate array of bytes in byteconverter but I haven't found it. Can you give me an example?

B4X:
 t1,h1 as double

str as string="/"

'concatenate 2 measures (t1,h1) with string
'convert t1 double to array of bytes , string to array of bytes and h1 to array of bytes)


'how to concatenate these 3 array of bytes?
 
Upvote 0

inakigarm

Well-Known Member
Licensed User
Longtime User
In an ideal environment (1 sensor attached to Arduino) I've no need to concatenate strings

But if I've several sensors attached to an Arduino and want to receive/send the measures via Serial (connected or bluetooth), I'll need to identify:
- from which sensor I received the stream --> tagging the data (ex: temp, hum, rotary sensor, keypad, etc..) with the values and then streaming, at end device I will be able to process the data knowing from which sensor I receive the data stream and take decissions about this.
- when receiving a data stream on Arduino, which is the sensor (pins) that must "rewrite" his values from the data stream received

B4R/B4X and his core control functions can make this data processing a simple case
 
Upvote 0

inakigarm

Well-Known Member
Licensed User
Longtime User
Well, for me not as helpful & simple as if string functions were available ( Arduino IDE -core, S4A (scratch for Arduino), snap (Berkeley) has String functions)

Waiting for ESP8266 library with mqtt client for a more simple solution

P.D:
Is possible to access string functions (i.e concat) with inline C/C++ code?
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
String concatenation with the Arduino String object is very problematic and should be avoided.
It is likely to cause the heap to become fragmented and then cause the program to fail in strange ways.
There are several features in B4R that provide alternative ways that do not depend on heap memory.

For example in B4A you would write:
B4X:
Log("x = " & x)
In B4R:
B4X:
Log("x = ", x)
Same result without requiring the allocation of a continuous memory range to store the concatenated string (note that there is another hidden optimization here, the constants strings will only be stored in the flash memory).

The same is true when you work with AsyncStreams. You are expected to call Write multiple times instead of a single call with the full message.
The performance will be exactly the same and it doesn't require any memory allocation.

There are many related discussions about this issue. For example:
http://forum.arduino.cc/index.php?topic=124367.0
http://stackoverflow.com/questions/9168907/arduino-crashes-and-errors-when-concatenating-strings

BTW, when I created the WebSocket library I based it on an existing open source project. It did use the Arduino String object for the protocol implementation.
It was very unreliable due to to memory issues. I rewrote it to avoid using any dynamic memory and it now works perfectly.

B4R memory tutorial: https://www.b4x.com/android/forum/threads/memory-variables-and-objects.65672/#content

If you really want to create large strings then you can use the ByteConverter library to copy to arrays of bytes together. Strings in B4R are exactly like bytes with an additional null byte.

I would be happy to see the actual code and try to help you implement it in the "B4R way".
 
Upvote 0

inakigarm

Well-Known Member
Licensed User
Longtime User
An example of string concatenation with byteconverter:

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public Serial1 As Serial  
    Public timer1 As Timer
    Public byteconv As ByteConverter
  
    Public count As Int                                'Counter in Timer1
    Dim strlength As Int                            'Length of destination String
  
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
  
    timer1.Initialize("Timer1_Tick",1000)
    timer1.Enabled=True
  
End Sub

Sub Timer1_Tick
      
    count=count+1                                      
    Dim str1 As String="Counting:  "                'string1 to concatenate
    Dim str2 As String=count                        'with string2
      
    strlength=str1.Length+str2.Length                'Length of destination String
      
    Dim bytes(strlength) As Byte
    byteconv.ArrayCopy(str1.getbytes,0,bytes,0,str1.Length)
    byteconv.ArrayCopy(str2.GetBytes,0,bytes,str1.Length,str2.Length)
      
    Log(bytes)                                                 'concatenated "string" of string1 & string2

End Sub
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
In the next update there will be two new keywords:
JoinStrings and JoinBytes.

JoinStrings takes an array of strings and concatenates them to a single string.
JoinBytes takes an array of objects where each item is an array of bytes and concatenates them to a single array.

B4X:
Dim s As String  = JoinStrings(Array As String("Pi = ", cPI))
Dim b() as byte = JoinBytes(Array("abc".GetBytes, Array as Byte(13, 10)))

The advantage of the join methods over the standard string concatenation operator is that it concatenates all the elements at once (there can be many elements).

With that said, in most cases these methods are not required and there are better solutions that do not require any additional memory.
For example:
B4X:
Log("Pi = ", cPI)
AStream.Write("abc".GetBytes).Write(Array As Byte(13, 10))
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Please start a new thread in the questions forum. Post the relevant code and also post the outputs of:
B4X:
Log("stack: ", StackBufferUsage)
Log("ram: ", AvailableRAM)
Check it before and after the join strings.

Note that as written in the tutorial: https://www.b4x.com/android/forum/threads/strings-and-bytes.66729/#content you should avoid using JoinStrings if possible.
 
Upvote 0
Top