Change string to ordered index ?

General FreeBASIC programming questions.
fxm
Moderator
Posts: 12082
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Change string to ordered index ?

Post by fxm »

dodicat,

I don't understand.
Your code properly works for stringtype:

Code: Select all

#include "file.bi"

type stringtype  'can save and reload this type efficiently from disk
    as string * 18  value
    as long index
    as long occurrency
    declare operator cast() as string
end type

operator stringtype.cast() as string 'print out the stringtype results
print "'";value;"'"
print index
print occurrency
return ""
end operator

sub loadfile(file as string,b() as stringtype)
   If FileExists(file)=0 Then Print file;" not found":Sleep:end
   var  f=freefile
    Open file For Binary Access Read As #f
    If Lof(f) > 0 Then
      Get #f, , b()
    End If
    Close #f
end sub

Sub savefile(filename As String,p() As stringtype)
    Dim As Integer n
    n=Freefile
    If Open (filename For Binary Access Write As #n)=0 Then
        Put #n,,p()
        Close
    Else
        Print "Unable to load " + filename
    End If
End Sub

dim as string z="AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"

  #define range(f,l) Int(Rnd*((l+1)-(f))+(f))

dim as stringtype st(1 to 10)
'create some instances of stringtype
for n as long=1 to ubound(st)
    with st(n)
        .value=mid(z,range(1,(52-18)),18)
        .index=n
        .occurrency=range(5,15)
    end with
next n
print "Save this data to file:"
print
for n as long=lbound(st) to ubound(st) 'show them
    print st(n)
    next
print "____________________________"
print

savefile("text.txt",st())

erase st

'reload from drive

var lngth=filelen("text.txt")\sizeof(stringtype) 'get incoming array dimension
dim as stringtype y(1 to lngth)
loadfile("text.txt",y())
print "Returned data:"
print
for n as long=lbound(st) to ubound(st) 'show them
    print y(n)
    next
sleep
 

Code: Select all

Save this data to file:

'fGgHhIiJjKkLlMmNnO'
 1
 8

'JjKkLlMmNnOoPpQqRr'
 2
 13

'kLlMmNnOoPpQqRrSsT'
 3
 12

'FfGgHhIiJjKkLlMmNn'
 4
 15

'QqRrSsTtUuVvWwXxYy'
 5
 15

'JjKkLlMmNnOoPpQqRr'
 6
 12

'BbCcDdEeFfGgHhIiJj'
 7
 12

'AaBbCcDdEeFfGgHhIi'
 8
 10

'aBbCcDdEeFfGgHhIiJ'
 9
 10

'OoPpQqRrSsTtUuVvWw'
 10
 13

____________________________

Returned data:

'fGgHhIiJjKkLlMmNnO'
 1
 8

'JjKkLlMmNnOoPpQqRr'
 2
 13

'kLlMmNnOoPpQqRrSsT'
 3
 12

'FfGgHhIiJjKkLlMmNn'
 4
 15

'QqRrSsTtUuVvWwXxYy'
 5
 15

'JjKkLlMmNnOoPpQqRr'
 6
 12

'BbCcDdEeFfGgHhIiJj'
 7
 12

'AaBbCcDdEeFfGgHhIi'
 8
 10

'aBbCcDdEeFfGgHhIiJ'
 9
 10

'OoPpQqRrSsTtUuVvWw'
 10
 13
Obviously, this does not work for UDTs with a variable length string field at least.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Change string to ordered index ?

Post by MrSwiss »

dodicat, you might want to change from String * 18, to ZString * 19, in the UDT.
Simplified code (of your's, without actually reading/writing file) but, with a Let
Operator for simpler assignment and, a 'fixed' Cast Operator:

Code: Select all


#include "file.bi"

' ----- Type start -----
type stringtype
    As ZString * 19 zstr    ' we don't want the header of string, just the data
    As ULong        length
    Declare Operator Let(ByRef As Const String)
    declare operator cast() as String
End Type

Operator stringtype.let(ByRef s As Const String) 
    If Len(s) > 18 Then Print "String to long!" : Exit Operator

    This.zstr = *StrPtr(s)
    This.length = Len(s)
End Operator

Operator stringtype.cast() As String ' return the stringtype content
    Return This.zstr & " - " & This.length
End Operator
' ----- Type end -----

' init randomizer
Randomize(Timer, 3)
For w As UInteger = 1 To 1000
    Rnd() : Rnd() : Rnd() : Rnd() : _
    Rnd() : Rnd() : Rnd() : Rnd() 
Next
' init randomizer - finished

dim as string z="AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"

#Define range(f,l) Int(Rnd*((l+1)-(f))+(f))

ReDim As stringtype st(0 to 9)
Dim As ULong    slen = 18 

'create some instances of stringtype
for n as ULong = LBound(st) to ubound(st)
    st(n) = Mid(z, range(1, (52 - slen)), slen)
Next n

print "Save this data to file:"
print
for n as ULong = LBound(st) To ubound(st) 'show them
    print st(n)
next
print "____________________________"
Print : Erase(st)

Sleep
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Change string to ordered index ?

Post by dodicat »

If you save a udt array with fixed length string fields via FreeBasic, then you are able to reload into another similar udt array. (as fxm demonstrates)
But if you have a raw ascii or text file you don't seem able to lay all the characters out in a given udt array with fixed length strings.
But success is achieved by using ubyte array fields.
Example.

Code: Select all


#include "file.bi"

Type arraytype 
    As Ubyte a(1 To 50)
    As Ubyte b(1 To 50)
    As Ubyte c(1 To 10)
End Type

Type stringtype
    As String * 50 a
    As String * 50 b
    As String * 10 c
End Type

Sub printout(u As stringtype)
    Print "'";u.a;"'"
    Print "'";u.b;"'"
    Print "'";u.c;"'"
End Sub

Sub loadfiletoarray overload(file As String,b() As stringtype)
    If Fileexists(file)=0 Then Print file;" not found":Sleep:End
    Var  f=Freefile
    Open file For Binary Access Read As #f
    If Lof(f) > 0 Then
        Get #f, , b()
    End If
    Close #f
End Sub

Sub loadfiletoarray(file As String,b() As arraytype)
    If Fileexists(file)=0 Then Print file;" not found":Sleep:End
    Var  f=Freefile
    Open file For Binary Access Read As #f
    If Lof(f) > 0 Then
        Get #f, , b()
    End If
    Close #f
End Sub


Function loadfiletostring(file As String) As String
    If Fileexists(file)=0 Then Print file;" not found":Sleep:End
    Var  f=Freefile
    Open file For Binary Access Read As #f
    Dim As String text
    If Lof(f) > 0 Then
        text = String(Lof(f), 0)
        Get #f, , text
    End If
    Close #f
    Return text
End Function

Sub savefile(filename As String,p As String)
    Dim As Integer n
    n=Freefile
    If Open (filename For Binary Access Write As #n)=0 Then
        Put #n,,p
        Close
    Else
        Print "Unable to load " + filename
    End If
End Sub
'====================================== START HERE ==============

'create a raw string of digits ( multiples of 110 to suit fields)
Dim As String g=String(10*110,0)
For n As Long=0 To Len(g)-1
    g[n]=48+Rnd*9
Next


'save this raw string to text file
savefile("text.txt",g)

g=""

'================================================================
'======================== Now work with the text file ===========

'1) stringtype
Var lngth=Filelen("text.txt")\Sizeof(stringtype) 'get load dimension

Dim As stringtype s(1 To lngth)

'load into stringtype
loadfiletoarray("text.txt",s())

'now work with stringtype
Print "stringtype array elements .a, .b, .c from file"
For n As Long=1 To Ubound(s)
    printout s(n)
    Print 
Next

Print

'check
Print "Check"
Dim As String acc
For n As Long=1 To Ubound(s)
    acc+=s(n).a+s(n).b+s(n).c
Next
Print

Print "original text file"
Dim As String L= loadfiletostring("text.txt")
Print L
Print "returned string from stringtype"
Print acc
Print Iif(acc=L,"OK","ERROR")
Print "Press a key to use arraytype"   
Sleep

'2) Use arraytype now
lngth=Filelen("text.txt")\Sizeof(arraytype)
Dim As arraytype a(1 To lngth)

Redim s(1 To lngth)  're-use the stringtype array

loadfiletoarray("text.txt",a())'load to arraytype

'transfer arraytype to stringtype
For n As Long=1 To Ubound(a)
    For m As Long=1 To 50: s(n).a+= Chr(a(n).a(m)):Next
    For m As Long=1 To 50: s(n).b+= Chr(a(n).b(m)):Next
    For m As Long=1 To 10: s(n).c+= Chr(a(n).c(m)):Next
    Next
    
            Print
            Print "Returned string fields"
            
            For n As Long=1 To Ubound(s)
                printout s(n)
                Print 
            Next
            
            Print "Check"
            acc=""
            
            For n As Long=1 To Ubound(s)
                acc+=s(n).a+s(n).b+s(n).c
            Next
            Print
            
            Print "original text file"
            L= loadfiletostring("text.txt")
            Print L
            Print "returned string from stringtype but via arraytype"
            Print acc
            Print Iif(acc=L,"OK","ERROR")
            
            
            sleep
            
            
            Kill "text.txt"
            
            
             

              
Lost Zergling
Posts: 534
Joined: Dec 02, 2011 22:51
Location: France

Re: Change string to ordered index ?

Post by Lost Zergling »

NOTE & precision : Till 0.991 release, the actual source of a bug that was incorrectly corrected by the change from Integer to uLong and that induces a different operation in 32 and 64 bits had been identified: it was actually an overrun on a zstring ptr. The move from Integer to uLong did not really fix the bug but just delayed its occurrence. On the latest online version, the bug was fixed and the use of Integer in the udt does not pose any new problem identified (32 & 64 bits) nor different behaviour. The bugfix was not precisely reported ("Corrections of several bugs").
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Change string to ordered index ?

Post by MrSwiss »

@Lost Zergling, posting "fake news", is bad, really bad news ...

First: there was not ever a: 0.991 release. The last release before: 1.00.0 was: 0.90.1.
IMO, not knowing something, as simple as that, means simply: "blah, blah".

Reason:
SizeOf(Integer), in FBC 32 returns: 4 (same for UInteger or (any sort of) Ptr), aka: 32 bit variable.
SizeOf(Integer), in FBC 64 returns: 8 (same for UInteger or (any sort of) Ptr), aka: 64 bit variable.
This is the reason that its called a dynamic size variable (Pointer size).

SizeOf(ULong) returns always: 4 (independent of 32/64 bit compiler), because of the simple fact,
that it is a: fixed size variable.
Lost Zergling
Posts: 534
Joined: Dec 02, 2011 22:51
Location: France

Re: Change string to ordered index ?

Post by Lost Zergling »

MrSwiss,
1. There was indeed a Beta 0.991 (not archived) (there is no Beta 1.00 yet, therefore there was an Alpha 1.00)
2. I do not pretend the SizeOf(Integer) is same in 32 & 64, just it is transparent to user in the intended use of the software
The tool has been designed to prevent programmer having to use pointers when it is not absolutely needed.
Other programming languages compete with us on this point.
As soon has your programming level you allow it, you do not need the tool.
I made a clarification about the bugfix that was made not for the purpose of provoking you but because this correction was not drawn, especially in case someone(s) would use the tool in a previous release. You pointed it out, I thought clarification was needed.
Although I am flattered by the interest you have in me, I am somewhat upset by the tone of your answer.
I suggest avoiding accusing us unnecessarily.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Change string to ordered index ?

Post by MrSwiss »

Lost Zergling,

The tool I'm referring to is called: FBC, aka: FreeBASIC Compiler.
... just a short clarification ...

Whatever you are referring to, escapes me ...
(that memory leaking LZLE, can't possibly be meant)
Lost Zergling wrote:I suggest avoiding accusing us unnecessarily.
People referring to themselfs in this way are usually of Royal Blood.
The French-People are known, to chop Royal Head's off.
Lost Zergling
Posts: 534
Joined: Dec 02, 2011 22:51
Location: France

Re: Change string to ordered index ?

Post by Lost Zergling »

Hum. Could you ignore I was reffering LZLE and not FBC. Missunderstandings, must be.
A Zergling ? Royal Blood ? Who knows...
Post Reply