This looks like a Bug
I have a TYPE OrderIt...END TYPE With 15 STRING * x elements.
Dim Order as OrderIt
I open the file as RANDOM ......... Len = Len(Order).
Using #Lang "fblite" when displaying the records they are all screwed up.
After much searching I said Print Len(Order) which printed 304. When I manually total them I get 289
which explains why the records are all messed up.
I get the impression that every field gets 1 added to it. Ie Item1 AS STRING * 10 ends up as STRING * 10 + 1 etc.
The prog starts off with - DEFINT A-Z.
I am using the latest FBC and FBide
At this stage my program compiles without errors, but.....
Type..End Type QB/FBlite bug ?
-
- Posts: 248
- Joined: Jul 01, 2010 9:35
Type..End Type QB/FBlite bug ?
Last edited by Theunis Jansen on Mar 22, 2013 13:58, edited 1 time in total.
Re: Type..End Type QB/FBlite bug ?
Yes:Theunis Jansen wrote:I get the impression that every field gets 1 added to it. Ie Item1 AS STRING * 10 ends up as STRING * 10 + 1 etc.
Code: Select all
Dim As String * 10 s
Print Sizeof(s)
Code: Select all
Type UDT
Dim As String * 10 s
End Type
Print Sizeof(UDT)
.....
Special note on fixed length strings
Currently, fixed-length string fields of String * N type have an extra null terminator at their end, for compatibility with C strings, making them incompatible with QB strings inside Types, because they actually use up N+1 bytes, instead of just N bytes. A possible work-around is to declare the field As String * (N-1), though this will not work in future releases if the null terminator is removed. Another alternative is to use a Byte array with the proper size.
.....
See also the second example.
-
- Posts: 248
- Joined: Jul 01, 2010 9:35
Re: Type..End Type QB/FBlite bug ?
Thanks FXM
I will try the (N - 1) suggestion.
But this is a rather major incompatibility
I will try the (N - 1) suggestion.
But this is a rather major incompatibility
-
- Posts: 248
- Joined: Jul 01, 2010 9:35
Re: Type..End Type QB/FBlite bug ?
@FXM
when you come to STRING * 1 then it cannot be done because of the default string length. So this only works of the N-x is 2 or more.
Looks like I will have to figure out a BINARY read of the DATA, but then another problems shows up when I put the DATA unless I Also do it in BINARY.
My one program has 22 elements and the one I am busy with has 15.
Oh well to get past the Old DOS number of files per directory I wrote my own FAT type file but that was about 15 years ago. (There were over 2000 Club members)
when you come to STRING * 1 then it cannot be done because of the default string length. So this only works of the N-x is 2 or more.
Looks like I will have to figure out a BINARY read of the DATA, but then another problems shows up when I put the DATA unless I Also do it in BINARY.
My one program has 22 elements and the one I am busy with has 15.
Oh well to get past the Old DOS number of files per directory I wrote my own FAT type file but that was about 15 years ago. (There were over 2000 Club members)
Re: Type..End Type QB/FBlite bug ?
The other alternative is to use Ubyte arrays with the proper sizes, and procedures to convert string->ubyte() and ubyte()->string:
[Edit]
Code modified as proposed by counting_pine below.
Code: Select all
Type UDT Field = 1
Dim As Ubyte b1 (0 To 9)
Dim As Ubyte b2 (1 To 15)
End Type
Function UbyteToString (ub() As Ubyte) As String
Dim As String s = Space(Ubound(ub) - Lbound(ub) + 1)
For I As Integer = Lbound(ub) To Ubound(ub)
s[I - Lbound(ub)] = ub(I)
Next I
Return s
End Function
Sub StringToUbyte (Byref s As String, ub() As Ubyte)
For I As Integer = 0 To Len(s) - 1
If I <= Ubound(ub) Then
ub(I + Lbound(ub)) = s[I]
End If
Next I
For I As Integer = Len(s) To Ubound(ub) - Lbound(ub)
ub(I + Lbound(ub)) = 0
Next I
End Sub
Dim As UDT u
Print Sizeof(u)
Print
StringToUbyte("0123456789", u.b1())
StringToUbyte("ABCDEFGHIJKLMNO", u.b2())
Print UbyteToString(u.b1())
Print UbyteToString(u.b2())
Sleep
Code modified as proposed by counting_pine below.
Last edited by fxm on Mar 22, 2013 19:15, edited 1 time in total.
-
- Site Admin
- Posts: 6323
- Joined: Jul 05, 2005 17:32
- Location: Manchester, Lancs
Re: Type..End Type QB/FBlite bug ?
Ubyte arrays are the preferred method for several reasons, including the fact that if we remove the null terminator in the future, all the types using them will break again!
When making an array of a specific size, a good idiom is to use 'arrayname(0 to size-1)' or 'arrayname(1 to size)'. This makes it obvious how large the array is.
If you use a lower bound of 1 (i.e. something that's not 0), then UbyteToString() will need to be updated as follows:EDIT: fixed oversight pointed out by fxm
When making an array of a specific size, a good idiom is to use 'arrayname(0 to size-1)' or 'arrayname(1 to size)'. This makes it obvious how large the array is.
If you use a lower bound of 1 (i.e. something that's not 0), then UbyteToString() will need to be updated as follows:
Code: Select all
Function UbyteToString (ub() As Ubyte) As String
Dim As String s = Space(Ubound(ub) - Lbound(ub) + 1)
For I As Integer = Lbound(ub) To Ubound(ub)
s[I - Lbound(ub)] = ub(I)
Next I
Return s
End Function
-
- Posts: 248
- Joined: Jul 01, 2010 9:35
Re: Type..End Type QB/FBlite bug ?
I fixed my problem. Opened two files - 1 as BINARY 2. as RANDOM
Calculated the number of files used For i=1 to NumberRecords...Next
Read the BINARY file using A$=INPUT$(289,i) (289 = Total for the elements). Converted the String with Mid$... to the TYPE... END TYPE elements and saved it to the Random file.
Set the Seek Position for the next record etc etc. until the FOR...NEXT ended
Calculated the number of files used For i=1 to NumberRecords...Next
Read the BINARY file using A$=INPUT$(289,i) (289 = Total for the elements). Converted the String with Mid$... to the TYPE... END TYPE elements and saved it to the Random file.
Set the Seek Position for the next record etc etc. until the FOR...NEXT ended