Page 1 of 1
Filesystem
Posted: Fri Jan 02, 2009 6:32 am
by Zooker
The filesystem in PB seems more difficult to use in comparison to the Basic Random read & write put & get routines. Would it be possible to
make files all strings and use a val or other similar comand to change the
fields that need to be changed to numbers. I am re-writing a program I had written in Basic PDS tto a windows program? Purebasic seems to be the only Basic that works in Vista 64 at all and I sure would like to be able to make it work now that I've bought it!!

Posted: Fri Jan 02, 2009 6:57 am
by citystate
I'm not sure what you mean, Zooker
by "making files all strings" do you mean, read the data from the file
as a string? if so, is this snippet the kind of thing you're looking for?
Code: Select all
if openfile(0,filename$)
while eof(0)=0
s$ = readstring(0)
;<insert string handling code here>
debug s$
wend
closefile(0)
endif
I'm sure you'll find PureBasic up to the task...
Posted: Fri Jan 02, 2009 7:04 am
by idle
Is this what you need?
oh well you got both read and write!
Code: Select all
somelong.l = 123456
strOut.s ="Some test data" + Chr(13) + Chr(10) + "and a new line" + Chr(13) + Chr(10)
strOut + "some numbers " + Str(somelong) + " some binary " + RSet(Bin($FF),8) + " hex " + Hex(255) + Chr(13) + Chr(10)
sfile.s = "C:\test.text"
OpenFile(1,sfile)
;FileSeek(1,Lof(1)) ;uncomment to append file
WriteData(1,@strOut,Len(strOut))
CloseFile(1)
Filesystem
Posted: Fri Jan 02, 2009 6:21 pm
by Zooker
Something More like this
Structure
Name as string
Age as string
Job as string
Height as string
end structure
Writeline Name |
WriteLine Age |> Basic did al this by saying Put #1 Structure Basically
WriteLine Job |
WriteLine Height |
Print Val(Age) as Number ; Changes string to Number
Posted: Fri Jan 02, 2009 6:40 pm
by Kaeru Gaman
you can use fixlength strings to build the structure.
use WriteString to put them into the file.
you could also use WriteData and put a complete structured Array in one into a file.
... but after all, there is no gain in using strings only for data format.
a Quad stores numbers up to 9223372036854775807 in 8byte.
as a string you need 20 byte in ANSI resp. 40 byte in Unicode to store such a number.
Basic did al this by saying Put #1 Structure Basically
"Basic" is not a Produkt name!
PureBasic is also a BASIC dialect.
if you want to compare different Basics, please state their name!
Posted: Fri Jan 02, 2009 9:12 pm
by blueb
Here's a small sample of a PureBasic record....
Code: Select all
Structure Layout
Name.s{50} ; string max. size = 50 chars
Age.l ; type is a LONG
Job.s{50}
Height.s{20}
EndStructure
Dim Rec.Layout(50) ; Create enough room for 50 records
Rec(0)\Name = "Barry Smith"
Rec(0)\Age = 34
Rec(0)\Job = "Account Manager"
Rec(0)\Height = "5Ft 6"
Rec(1)\Name = "Bob Jackson"
Rec(1)\Age = 58
Rec(1)\Job = "CEO"
Rec(1)\Height = "6 Ft 0 In"
Text$ = Rec(1)\Name + "'s age is: " + Str(Rec(1)\age )
MessageRequester("Find the second record", Text$)
Posted: Mon Jan 05, 2009 12:56 am
by pdwyer
Zooker,
I'm not sure if this question is answered or not to your satisfaction. There is some code in the tips section that people have written to handle record like reads and writes to files.
Personally though, I think you would be better served with a little SQLite DB, Using SQLite in your app adds about 350k to the exe size but the data files created are tiny and it gives you more query power, handles your record updates and deletions and is scalable should your app get bigger.
Posted: Mon Jan 05, 2009 8:22 pm
by harkon
Zooker,
In the following code is a copy of the QB help example for the "PUT" function. I have included a substitute with procedures to somewhat emulate the behavior of the QB functions. I have used this sort of file and record I/O before to access data files created by legacy applications. As pdwyer mentioned, I would move to using a SQLite DB. It is miles ahead of the way QB used to do this, and is scalable to very large record numbers. As you are recoding anyway, it really makes sense. If you want to play though to get familiar with QB, I hope the attached code helps.
Code: Select all
;---------- Code from QB "PUT" help example ---------
; ' Read a name and a test score from the console.
; ' Store each name and score as a record in a
; ' random-access file.
;
; ' Define record fields.
; TYPE TestRecord
; NameField As STRING * 20
; ScoreField As SINGLE
; End TYPE
;
; ' Open the test data file.
; Dim FileBuffer As TestRecord
; OPEN "TESTDAT.DAT" For RANDOM As #1 LEN = Len(FileBuffer)
;
; ' Read pairs of names and scores from the console.
;
; CLS ' Clear screen
; I = 0
; DO
; I = I + 1
; INPUT "Name ? ", FileBuffer.NameField
; INPUT "Score? ", FileBuffer.ScoreField
; INPUT "-->More (y/n)? ", Resp$
; PUT #1, I, FileBuffer
; LOOP Until UCASE$(MID$(Resp$, 1, 1)) = "N"
;
; PRINT I; " records written."
;
; CLOSE #1
;------------- start of PB code -----------------
;setup structure
Structure TestRecord
NameField.s{20}
ScoreField.f
EndStructure
; Open the test data file.
Dim FileBuffer.TestRecord(0)
OpenFile(1,"C:\Program Files\PureBasic\Projects\Test\TESTDAT.DAT")
Global TestRecLen.w=SizeOf(TestRecord)
; Procedures to make this as QB as possible
Procedure QBPut(Filenum.w,RecordNum.w,*recordpointer)
FileSeek(FileNum,(RecordNum-1)*TestRecLen)
WriteData(Filenum,*recordpointer,TestRecLen)
EndProcedure
Procedure.s QBInput(InputString.s)
Print(Inputstring)
ProcedureReturn Input()
EndProcedure
;Open a console and clear it
OpenConsole()
EnableGraphicalConsole(1)
ClearConsole()
I=0
Repeat
I=I+1
FileBuffer(0)\NameField=QBInput("Name ? ")
FileBuffer(0)\Scorefield=ValF(QBInput("Score ? "))
Resp$=QBInput("-->More (y/n)? ")
QBPut(1,I,@FileBuffer(0))
Until UCase(Resp$)="N"
PrintN(Str(I) + " records written")
CloseFile(1)
;this will keep the console open until you hit a key
Repeat
Delay(100)
Until Inkey()<>""
The absolute beauty of PB is that a whole lot can be accomplished without a great deal of extra coding. You shoud be aware though that in PB strings are null terminated. In QB you could store chr$(00) in a string, in PB that will terminate the string and there will be no data after that. You will need to use memory buffers to store binary data. This make PB far more efficient as string handling tends to be slow in most languages. Directly manipulating memory is far more efficient.
Post back if you have any questions.
Edited
moved procs to after "Global TestRecLen" as otherwise the procs didn 't see the value.