|
Post by NoVaGene on Jul 10, 2004 5:04:58 GMT -5
I need help on this piece of code. It is suppose to give the following results. a0 100 1.5 a1 200 2.5 I tried changing a$(loop1) = readtext (file, true) to a$(loop1) = readtext (file, false) and the result is again incorrect. However, if I use these:- a$(0)="a0" a$(1)="a1" b(0)=10 b(1)=20 c#(0)=1.5 c#(1)=2.5 ... it shows the correct output:- a0 10 1.5 a1 20 2.5 if I remarked to disable the lines, it produces the expected values. 'writestring(file, a$(loop1)) 'a$(loop1) = readtext (file, true) 'printr a$(loop1) Correct o/p:- 100 1.5 200 2.5 Not sure why. dim file, loop1 dim a$(1), b(1), c#(1) a$(0)="a0" a$(1)="a1" b(0)=100 b(1)=200 c#(0)=1.5 c#(1)=2.5
file = OpenFileWrite ("files\test.txt") if FileError () <> "" then print FileError (): end: endif for loop1=0 to 1 writestring(file, a$(loop1)) writeint (file, b(loop1)) writefloat (file, c#(loop1)) next CloseFile (file)
file = OpenFileRead ("files\test.txt") if FileError () <> "" then print FileError (): end: endif for loop1=0 to 1 a$(loop1) = readtext (file, true) b(loop1) = readint (file) c#(loop1) = readfloat (file) next CloseFile (file)
locate 0,1 for loop1=0 to 1 printr a$(loop1) printr b(loop1) printr c#(loop1) printr next 'for loop1 swapbuffers()
Many tks! Rgds, Lucas Tan
|
|
|
Post by AHBanen on Jul 10, 2004 8:54:36 GMT -5
Lucas, File I/O is always frustrating when the methods of writing and reading are not mirrored. In this case WriteString isn't mirrored by a ReadString. Moreover: "WriteString (file, text) writes text to the file. No carriage return or linefeed is appended. A zero byte string terminator is NOT appended" (Basic4GL Programmer's Guide) This means there is no easy way to tell - when reading back - how long a string is. There are several ways to circumvent that e.g. by also writing a sentinel value (CR/LF or chr$(0) (see below) or by first writing out the length of the string followed by the string. On reading back than read first the length of the string followed by reading back exactly that number of characters (I leave it up to you to test this method too). The easy solution could be to change the WriteString function so it also writes an optional EOS (end-of-string) character(s) and to create a ReadString function that reads a string until it encounters the same EOS char(s). Until then we'll have to improvise (= do it ourselfs)
dim file, loop1 dim a$(1), b(1), c#(1) dim tmp$, t$, sentinel$ sentinel$ = chr$(0)
a$(0)="a0" a$(1)="a1" b(0)=100 b(1)=200 c#(0)=1.5 c#(1)=2.5
file = OpenFileWrite ("files\test.txt") if FileError () <> "" then print FileError (): end: endif
for loop1=0 to 1 writestring(file, a$(loop1)+sentinel$) 'make sure a sentinel end-of-string value is witten too writeint (file, b(loop1)) writefloat (file, c#(loop1)) next
CloseFile (file) 'overwrite the original values in order not to get 'false positives' a$(0)="b1" a$(1)="b2" b(0)=911 b(1)=811 c#(0)=2.7 c#(1)=3.4
file = OpenFileRead ("files\test.txt") if FileError () <> "" then print FileError (): end: endif
for loop1=0 to 1 'there is no readstring so we read char-by-char t$ = "" tmp$ = readchar( file) while NOT EndOfFile(file) AND tmp$ <> sentinel$ t$ = t$ + tmp$ tmp$ = readchar( file) wend a$(loop1) = t$ 'a$(loop1) = readtext (file , true)
b(loop1) = readint (file) c#(loop1) = readfloat (file) next
CloseFile (file)
locate 0,1 for loop1=0 to 1
printr a$(loop1) printr b(loop1) printr c#(loop1) printr
next 'for loop1
swapbuffers()
File I/O is possible in Basic4GL (but RTFM first!) André P.S. I first coded my improvisation and only then looked into the manual
|
|
|
Post by NoVaGene on Jul 10, 2004 14:11:45 GMT -5
Tks André! I see your point here. I did try doing something like a$(0)="a0"+chr$(32) earlier so that a$(loop1) = readtext (file, true) would skip the space delimiter but not to the extend of reading char by char. Tks for the workaround. I was thinking of addressing this limitation to Tom as well to see if he can offer an elegant approach to read string such as this. Cheers! Lucas Tan PS: RTFM == read techniques from manual?
|
|
|
Post by AHBanen on Jul 10, 2004 15:00:55 GMT -5
Lucas, Your idea, using ReadText is probably better than my workaround using chars! The 'problem' with ReadText is that it read a string upto but not including the (first) whitespace character. When one realizes this, it is possible to see that when you use e.g. a TAB character to delimit the string you can use ReadChar as you were trying. But you need to read the whitespace character too!. See the example:
dim file, loop1 dim a$(1), b(1), c#(1) dim tmp$, t$, sentinel$ sentinel$ = chr$(9) ' tab (= whitespace)
a$(0)="a0" a$(1)="a1" b(0)=100 b(1)=200 c#(0)=1.5 c#(1)=2.5
file = OpenFileWrite ("files\test.txt") if FileError () <> "" then print FileError (): end: endif
for loop1=0 to 1 writestring(file, a$(loop1)+sentinel$) 'make sure a whitespace is witten too writeint (file, b(loop1)) writefloat (file, c#(loop1)) next
CloseFile (file) 'overwrite the original values in order not to get 'false positives' a$(0)="b1" a$(1)="b2" b(0)=911 b(1)=811 c#(0)=2.7 c#(1)=3.4
file = OpenFileRead ("files\test.txt") if FileError () <> "" then print FileError (): end: endif
for loop1=0 to 1 a$(loop1) = readtext (file , true) tmp$ = readchar(file) 'eat the whitespace b(loop1) = readint (file) c#(loop1) = readfloat (file) next
CloseFile (file)
locate 0,1 for loop1=0 to 1
printr a$(loop1) printr b(loop1) printr c#(loop1) printr
next 'for loop1
swapbuffers()
I think hat the way strings are written to files is stuck on a somewhat low level, making it very flexible and possible to to use your own format, but also making it a bit difficult to use in casual programming (at least when one's intermixing data types...). Basic4GL: flexible yet though... André P.S. RTFM: see www.google.nl/search?q=RTFM+acronym&ie=UTF-8&hl=en
|
|
|
Post by AHBanen on Jul 10, 2004 15:29:21 GMT -5
Lucas, Below another way to solve your problem this time using using WriteLine/ReadLine. Again there is this problem that Basic4GL appears to read upto but not including the newline. This can easily solved using a ReadChar to eat the newline. Maybe this is the easiest solution for 'casual intermixing' data types in File I/O...
dim file, loop1 dim a$(1), b(1), c#(1) dim tmp$
a$(0)="a0" a$(1)="a1" b(0)=100 b(1)=200 c#(0)=1.5 c#(1)=2.5
file = OpenFileWrite ("files\test.txt") if FileError () <> "" then print FileError (): end: endif
for loop1=0 to 1 writeLine(file, a$(loop1)) ' <== WriteLine NOT WriteString writeint (file, b(loop1)) writefloat (file, c#(loop1)) next
CloseFile (file) 'overwrite the original values in order not to get 'false positives' a$(0)="b1" a$(1)="b2" b(0)=911 b(1)=811 c#(0)=2.7 c#(1)=3.4
file = OpenFileRead ("files\test.txt") if FileError () <> "" then print FileError (): end: endif
for loop1=0 to 1 a$(loop1) = readLine (file ) ' ReadLine NOT ReadText tmp$ = readchar(file) 'eat the newline
b(loop1) = readint (file) c#(loop1) = readfloat (file) next
CloseFile (file)
locate 0,1 for loop1=0 to 1
printr a$(loop1) printr b(loop1) printr c#(loop1) printr
next 'for loop1
swapbuffers()
Is it BASIC, is it OpenGL? No, it is Basic4GL!
André
|
|