Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Binary file write
#1
Here is some annoying code for you:

Code: (Select All)
Type struct
    s As String
End Type

Dim structx As struct
structx.s = "abc": Print structx.s
Print Len(struct)
structx.s = "abcdef": Print structx.s
Print Len(struct)

Open "testfile.xxx" For Binary As #1
' UDT must have fixed size.
Put 1, 1, structx
Code: (Select All)
Dim x2(1 To 1024) As String
For l = 1 To 1024
    x2(l) = Str$(l)
Next
Open "filetest.xxx" For Binary As #1
' Cannot pass array of variable-length strings.
Put 1, 1, x2()
Maybe these can be tweaked someday!?

Erik.
Reply
#2
LOL. VLS member inside UDT. Object-oriented programming in QB64, here we come!

The array of strings problem you presented is for the simple reason that it will have to write the lengths of the string, at the time the file is being created and written to. Otherwise how are you going to tell one string member from another later?

By making all members of a specific length, you are helping the QB64 compiler indicate where one string starts and where it ends, out of many thousands potentially.

Much binary code must store the length of the string first of all before writing the string. This is the only way (at a low level) to reliably bring back data to the state it was when a file had to be created to hold those strings and other stuff.

What are you trying to do with the array of VLS's anyway?

Just create an UDT which in the least, there is an integer length, and the other member is a fixed-length string. Must make the string as large as you think a single string member could be. It sucks, but that is the most sane way to go about things.
Reply
#3
Quote:What are you trying to do with the array of VLS's anyway?
I have a Screen Editor dimensioned a large array I am writing to the file using binary write variable length string array which is slow.

Binary write because Linux might strip 013 ascii from the file.

For example:

Code: (Select All)
Linux = -1
Dim Array(1024) As String
For L = 1 To 1024
    Array(L) = Str$(L)
Next

Open "testfile.xxx" For Binary As #1
For L = 1 To 1024
    X$ = Array(L)
    For X = 1 To Len(X$)
        Y$ = Mid$(X$, X, 1)
        Put 1, , Y$
    Next
    If Linux Then
        Z$ = Chr$(10)
        Put 1, , Z$
    Else
        Z$ = Chr$(13)
        Put 1, , Z$
        Z$ = Chr$(10)
        Put 1, , Z$
    End If
Next
End

Note: You cannot Put 1,,Chr$(10) or Put 1,,Asc(Chr$(10))
Reply
#4
VLS variable length strings is old known problem for QB64 as well as arrays in UDT.

There are work arounds as old as this problem.

You're right! I am annoyed you bringing this up this old thing again. ;-))

It's like I am lazy and people keep coming up to me and saying, Hey, you're lazy!
b = b + ...
Reply
#5
(09-23-2023, 03:57 AM)eoredson Wrote:
Quote:What are you trying to do with the array of VLS's anyway?
I have a Screen Editor dimensioned a large array I am writing to the file using binary write variable length string array which is slow.

Binary write because Linux might strip 013 ascii from the file.

For example:

Code: (Select All)
Linux = -1
Dim Array(1024) As String
For L = 1 To 1024
    Array(L) = Str$(L)
Next

Open "testfile.xxx" For Binary As #1
For L = 1 To 1024
    X$ = Array(L)
    For X = 1 To Len(X$)
        Y$ = Mid$(X$, X, 1)
        Put 1, , Y$
    Next
    If Linux Then
        Z$ = Chr$(10)
        Put 1, , Z$
    Else
        Z$ = Chr$(13)
        Put 1, , Z$
        Z$ = Chr$(10)
        Put 1, , Z$
    End If
Next
End

Note: You cannot Put 1,,Chr$(10) or Put 1,,Asc(Chr$(10))

Ah now we get to real problem! Trying to please Linux and all it's possible flavors.

Well I leave that up to @mnrvovrfc ;-)) like that's not old too LOL
b = b + ...
Reply
#6
It's not that difficult.

Code: (Select All)
DIM ff AS LONG
$IF WIN THEN
DIM CRLF AS STRING * 2
CRLF = CHR$(13) + CHR$(10)
$ELSEIF LINUX THEN
DIM CRLF AS STRING * 1
CRLF = CHR$(10)
$ELSE 'it's... grymmjack's computer! Isn't it? (scratch head)
DIM CRLF AS STRING * 1
CRLF = CHR$(13)
$END IF

ff = FREEFILE
OPEN "blah.bin" FOR BINARY AS ff
PUT #1, , CRLF
CLOSE ff

Or could check result of `_OS$()` function. For an executable it doesn't matter because the three main operating systems use different formats: Linux uses ELF.
Reply
#7
Quote:Trying to please Linux and all it's possible flavors.
Out of all the 50+ linux os variants I don't think I could even touch every flavor Angry 

Why they cut out 013 in the first place still bothers me.
Reply
#8
Even Windows removes the 13 now.   I tend to just write all CRLF as 10 and be done with it, anymore.
Reply
#9
I only ever mess with CHR$(10) in both Windows and Linux. It displays just fine in both. Don't see any reason to do a carriage return & line feed combo on Windows. Just do the line feed. No need to complicate matters with checking for OS$.
Tread on those who tread on you

Reply
#10
On the subject of CRLF I have wrote the following set of TEE utilities:

Erik.


Attached Files
.zip   TEE11.ZIP (Size: 76.42 KB / Downloads: 26)
Reply




Users browsing this thread: 3 Guest(s)