Posts: 54
Threads: 12
Joined: Apr 2022
Reputation:
2
Hi to all.
In my early years as a Pascal programmer, I remember that I could do something like this:
Code: (Select All)
Type T_Thing
Namez As String
Index(4) as integer
End Type
And then use this:
Code: (Select All)
A.Index(1)=5
It will be very useful for me... is there any option in the actual QB64PE? Maybe in the future?
Thank you very much
10 PRINT "Hola!  "
20 GOTO 10
Posts: 163
Threads: 20
Joined: Apr 2022
Reputation:
20
No in the sense that you are trying to implement. There is a workaround that I use. Basically you are storing numbers in a long string. Here is a demo of that. Arrays in UDT's has been on my wish list for years.
Code: (Select All)
' String Array Test
' Arrays must start at index 1
TYPE tUDT
longArray AS STRING * 1028 ' arraysize * 4 + 4
a AS INTEGER
b AS _BYTE
c AS LONG
longArray1 AS STRING * 1028
END TYPE
DIM udt AS tUDT
DIM iter AS LONG
FOR iter = 1 TO 256
SetArrayLong udt.longArray, iter, iter * 2000000
PRINT iter; ": "; getArrayLong(udt.longArray, iter)
SetArrayLong udt.longArray1, iter, iter * 2000000
PRINT iter; ": "; getArrayLong(udt.longArray1, iter)
NEXT
FUNCTION getArrayLong& (s AS STRING, p AS LONG)
IF p > 0 AND p * 4 + 4 <= LEN(s) THEN getArrayLong = CVL(MID$(s, p * 4, 4))
END FUNCTION
SUB SetArrayLong (s AS STRING, p AS LONG, v AS LONG)
IF p > 0 AND p * 4 + 4 <= LEN(s) THEN MID$(s, p * 4) = MKL$(v)
END SUB
FUNCTION getArraySingle! (s AS STRING, p AS LONG)
IF p > 0 AND p * 4 + 4 <= LEN(s) THEN getArraySingle = CVS(MID$(s, p * 4, 4))
END FUNCTION
SUB SetArraySingle (s AS STRING, p AS LONG, v AS SINGLE)
IF p > 0 AND p * 4 + 4 <= LEN(s) THEN MID$(s, p * 4) = MKS$(v)
END SUB
FUNCTION getArrayInteger% (s AS STRING, p AS LONG)
IF p > 0 AND p * 2 + 2 <= LEN(s) THEN getArrayInteger = CVI(MID$(s, p * 2, 2))
END FUNCTION
SUB SetArrayInteger (s AS STRING, p AS LONG, v AS INTEGER)
IF p > 0 AND p * 2 + 2 <= LEN(s) THEN MID$(s, p * 2) = MKI$(v)
END SUB
FUNCTION getArrayDouble# (s AS STRING, p AS LONG)
IF p > 0 AND p * 8 + 8 <= LEN(s) THEN getArrayDouble = CVL(MID$(s, p * 8, 8))
END FUNCTION
SUB SetArrayDouble (s AS STRING, p AS LONG, v AS DOUBLE)
IF p > 0 AND p * 8 + 8 <= LEN(s) THEN MID$(s, p * 8) = MKD$(v)
END SUB
You could do something similar with memory blocks but it is a bit more cluncky.
Posts: 485
Threads: 41
Joined: Apr 2022
Reputation:
40
@justsomeguy
I did something similar in my infamous decfloat stuff but the overhead is very high
when dealing with arrays in a type you usually want to access more than one element, possibly all elements so it's way faster to copy the string into a work array and afterwards copy the array back into the string
here's a demo
Code: (Select All)
_Title "array-memcpy-offset"
$Console:Only
_Dest _Console
Option _Explicit
Declare CustomType Library
Sub memcpy Alias "memmove" (ByVal dest As _Offset, ByVal source As _Offset, ByVal bytes As Long)
End Declare
Const amax = 1000
Const smax = 8 * (1 + amax)
Dim As Double sum, x(amax), y(amax)
Dim As String * smax sx
Dim As String * smax sy
Dim As _Offset sxo, axo, syo, ayo
Dim As Long i
sxo = _Offset(sx)
axo = _Offset(x(0))
syo = _Offset(sy)
ayo = _Offset(y(0))
sum = 0
For i = 0 To amax
x(i) = i
sum = sum + i
Next
Print sum
memcpy sxo, axo, smax 'copy x array into the string sx
sy = sx ' copy the string sx to string sy
memcpy ayo, syo, smax 'copy content of string sy to array y
sum = 0
For i = 0 To amax
sum = sum + y(i)
Next
Print sum
Posts: 4,692
Threads: 222
Joined: Apr 2022
Reputation:
322
03-04-2026, 11:45 PM
(This post was last modified: 03-04-2026, 11:48 PM by bplus.)
For an array of variable length strings:
Join$ will turn a String Array into a LongString$ and Split will pop an array out of a LongString$
Code: (Select All)
Sub Split (SplitMeString As String, delim As String, loadMeArray() As String)
Dim curpos As Long, arrpos As Long, LD As Long, dpos As Long 'fix use the Lbound the array already has
curpos = 1: arrpos = LBound(loadMeArray): LD = Len(delim)
dpos = InStr(curpos, SplitMeString, delim)
Do Until dpos = 0
loadMeArray(arrpos) = Mid$(SplitMeString, curpos, dpos - curpos)
arrpos = arrpos + 1
If arrpos > UBound(loadMeArray) Then ReDim _Preserve loadMeArray(LBound(loadMeArray) To UBound(loadMeArray) + 1000) As String
curpos = dpos + LD
dpos = InStr(curpos, SplitMeString, delim)
Loop
loadMeArray(arrpos) = Mid$(SplitMeString, curpos)
ReDim _Preserve loadMeArray(LBound(loadMeArray) To arrpos) As String 'get the ubound correct
End Sub
Function Join$ (arr() As String, delimiter$)
Dim i As Long, b$
For i = LBound(arr) To UBound(arr)
If i = LBound(arr) Then b$ = arr(LBound(arr)) Else b$ = b$ + delimiter$ + arr(i)
Next
Join$ = b$
End Function
Used successfully in UDT's for my Interpreter and my GUI among other things like avoiding Data and Read statements.
So an extra step or two but oh the power!
724 855 599 923 575 468 400 206 147 564 878 823 652 556 bxor cross forever
Posts: 187
Threads: 14
Joined: May 2024
Reputation:
20
this is just going to be requested. until the qb64pe developers give in. or until something else happens. how many more topics will we have of this?
meanwhile there is a small amount. of usage of _mem and its related functions. there are basic programmers. that don't know how fortunate they are. to have flexible string manipulation functions. although it doesn't include regular expressions.
array member inside udt. requires a serious amount of overhead. in qb64pe. a variable-length string is supported as member inside udt. that wasn't allowed in quickbasic/qbasic. i don't think it was allowed by vbdos nor by basic 7 pds neither. so something should be done about it.
support array member inside udt. because pascal supports it? well it will bring the other baggage about using arrays in general. such as option base. some people will expect that supported too. there was another topic about function pointers. oh i want an array of that in this language!
bring this thing toward oop. i don't want that. i'm sure most of you all don't neither. unfortunately begging for array member inside udt. is a step toward also having subprograms. as members of udt also. and other such things.
hopeless addict of dying in the first few levels of two particular console viewport "roguelike" games
Posts: 485
Threads: 41
Joined: Apr 2022
Reputation:
40
Yesterday, 02:14 PM
(This post was last modified: Yesterday, 02:16 PM by Jack.)
honestly, I don't understand why there are always naysayers and against progress
some people it seems are not happy with BASIC unless it conforms and does not extend the original BASIC's from the 1970's
mandatory line numbers, only one-line functions as in defn and tons of gotos and gosubs, almost forgot the mandatory LET although most basics would allow omitting the LET
Posts: 954
Threads: 52
Joined: May 2022
Reputation:
38
11 hours ago
(This post was last modified: 11 hours ago by Kernelpanic.)
@Ikerkaz - That's possible with a record array; I've posted about it a few times already.
PS: Extended with name
Code: (Select All)
'Recordarraybeispiel - 5. Maerz 2026
Option _Explicit
Type Thing
Namez As String
Index As Integer
End Type
Dim Liste(4) As Thing
Dim As Integer wert
Dim As String namen
Locate 2, 3
Input "Ganze Zahl eingeben: ", wert
Liste(1).Index = wert
Locate 3, 3
Print "Ihre Eingabe war: "; Liste(1).Index
Locate 5, 3
Input "Ihr Name: ", namen
Liste(2).Namez = namen
Locate 6, 3
Print "Ihr Name lautet: "; Liste(2).Namez
End
Posts: 243
Threads: 15
Joined: Apr 2024
Reputation:
30
(Yesterday, 01:32 AM)hsiangch_ong Wrote: this is just going to be requested. until the qb64pe developers give in. or until something else happens. how many more topics will we have of this?
meanwhile there is a small amount. of usage of _mem and its related functions. there are basic programmers. that don't know how fortunate they are. to have flexible string manipulation functions. although it doesn't include regular expressions.
array member inside udt. requires a serious amount of overhead. in qb64pe. a variable-length string is supported as member inside udt. that wasn't allowed in quickbasic/qbasic. i don't think it was allowed by vbdos nor by basic 7 pds neither. so something should be done about it.
support array member inside udt. because pascal supports it? well it will bring the other baggage about using arrays in general. such as option base. some people will expect that supported too. there was another topic about function pointers. oh i want an array of that in this language!
bring this thing toward oop. i don't want that. i'm sure most of you all don't neither. unfortunately begging for array member inside udt. is a step toward also having subprograms. as members of udt also. and other such things.
I understand why having an array in a UDT adds baggage to the compiler.
I honestly don't think supporting FIXED size arrays should add that much run time baggage. It's just an offset added to an offset !!!!
I don't think we should target support for dynamic arrays !
One of the thing I like about UDT's is the ability to just GET or PUT them to a file in one line of code ! For this the size of it does have to be known !
|