I’m probably not new with this case. I would like to fill up a given string value with a given char. I.e.:
Fill up “1111” on the right by “0” to the max length of 8 → Output: “11110000”
In the most other languages this function is called “LPAD” and “RPAD”. I was checking the String functions and couldn’t find any similar to this, maybe I just overlooked it or searched in the wrong documentation place. This function is so basic I can’t imagine it doesn’t exist in Xojo.
Sure, I see a workaround like adding “00000000” to the given string and then cut it down to the wanted length (2 operations).
Just wondering if this function really doesn’t exist in Xojo.
Background: I’m working with Binary strings and found out that ToBinary never returns a filled (length of 8,16,24, …) Binary and there is no option to get in the wanted Binary length.
Here’s an extension function that you can put in a module for left or right padding:
Public Function Pad(extends input as String, padCharacter as String = "0", left as Boolean = True, toLength as Integer = 16) As String
'// Example usage
' Var s as String = "1011"
' s = s.Pad("0", False, 8)
'
' Result: 10110000
var data() as String = input.ToArray( "" )
var originalLength as Integer = data.LastIndex
for index as Integer = originalLength to toLength - 2
if left then
data.AddAt( 0, padCharacter )
else
data.Add( padCharacter )
end if
next
Return String.FromArray( data, "" )
End Function
Var s As String s = “222” TextField1.Text = s s.remplir ( “0” , 20 ) TextField2.Text= s
Méthode remplir:
// byref Extends source as String, caracter as string, nombre as integer
’ Methode a copier :
’ Var s As String
’ s.remplir ( “X” , nombre )
For i As Integer = source.Length To nombre
source = source + caracter
Next
Exception err
Break
If you are doing a lot of string concatenation and your strings can be expected to get long you can use the following:
Function FastConcat()
// Declare an empty MemoryBlock
// BinaryStream will make the block larger as required
Var mResult As New MemoryBlock( 0 )
// Setup a BinaryStream to the memory block
Var bsResult As New BinaryStream( mResult )
// Perform some concatenation
For Counter as Integer = 0 to 1000000
bsResult.Write( "Some String" )
Next
// Close the stream
bsResult.Close
If mResult.Size = 0 Then
Return ""
Else
Return mResult.StringValue( 0, mResult.Size, Encodings.UTF8 )
End If
End Function
Thanks everyone for all the solutions. So as you all offer an own solution there seems no Xojo function available. I test all yours and implement one. Performance might not be my issue as I only want to fill up to 8 bits (1 byte).
I have two functions that makes this pretty easy. The first is a Replicate function and then I created a PADL and PADR so I could pad on either side of a value.
FUNCTION Replicate(Char As String, Number as integer) As String
'--- DUPLICATES A CHARACTER X NUMBER OF TIMES
Dim cString As String = ""
If char <> "" And Number <> 0 Then
For i As Integer = 1 To Number
CString = CString + Char
Next
End
Return CString
FUNCTION PADL(String2Pad As String,Length as Integer, PadChar As String) As String
Dim nLen As Integer
String2Pad = String2Pad.Trim
nLen = String2Pad.Length
Return Replicate(PadChar,Length - nLen) + String2Pad
FUNCTION PADL(String2Pad As String,Length as Integer, PadChar As String) As String
Dim nLen As Integer
nLen = String2Pad.Trim.len
RETURN String2Pad.Trim + REPLICATE(PadChar,Length - nLen)
I migrated from the Visual Foxpro world and these functions were built in.
Here’s a little optimization trick - using the Static keyword in the Replicate function, repeated calls to Replicate (with the same parameters) will be much faster.
function Replicate(c as string, n as Integer) as String
Static s as String = ""
// if we already created the string with the same values (c and n) then
// simply return it, rather than re-creating it
if s.length = n and left(s, c.length ) = c then
return s
end if
// otherwise, create the repeated string
for i as integer = 1 to n
s = s + c
next
return s
end if
You could combine this technique with the memoryBlock technique from @Ian_Kennedy to get a really fast version.
On my M1
100,000 characters, unprimed takes 250 microseconds or 0.25 milliseconds.
Public Function RepeatChars(ch as string, count as integer) As String
Static chars As String = ""
// Only allow single characters
If ch.Length > 1 Then
Raise New UnsupportedOperationException
End If
// make sure there's at least one character
If chars = "" Then
chars = ch
End If
// Make sure we're dealing with the right character
If chars.Left(1) <> ch Then
chars = chars.ReplaceAll(chars.Left(1), ch)
End If
// keep doubling until we have at least the number we need
While chars.Length < count
chars = chars + chars
Wend
// Return the count that we need
Return chars.Left(count)
End Function
Good catch - the bug was failing to clear the value of S before rebuilding it.
Fixed:
function Replicate(c as string, n as Integer) as String
#pragma BackgroundTasks false
Static s as String = ""
// if we already created the string with the same values (c and n) then
// simply return it, rather than re-creating it
if s.length = n and left(s, c.length ) = c then
return s
end if
// otherwise, create the repeated string
s = "" // clear the existing cached string (if any)
for i as integer = 1 to n
s = s + c
next
return s
end if
However, lots of the Xojo frameworks are not reentrant either, so if you are using Preemptive threading, you would probably shoot yourself in the foot elsewhere, too
That’s an invalid point. I’m used to write correct code in preemptive mode since the 80’s. If the Xojo framework is ok, I can write correct code. As Xojo is not a single thread system anymore, writing reusable functions with such concerns in mind is important.
Public Function Replicate(str As String, times As Int32) As String
// Binary string replication, by Rick A. (2025)
// I had this idea based on the Greg O. idea of producing a string by doubling a char
// until a big enough string and cutting the exact size
// That doubling screamed binary, so I though...
// Let's try the exact accumulation, it may be optimal and a small code
// Replicate() replicates strings n times, but faster than usual for large ones
Var pad As String = ""
Do Until times <= 0
If (times And 1) = 1 Then pad = pad + str
If times > 1 then str = str + str
times = times \ 2
Loop
Return pad
End Function
######### Test: ##########
For n as integer = 0 to 32
Var s As String = Replicate("X", n)
System.DebugLog s.Length.ToString + " -> " + s
Next
For n as integer = 0 to 32
Var s As String = Replicate("Rick", n)
System.DebugLog s.Length.ToString + " " + n.toString + " -> " + s
Next
Break