• Welcome to Dark Bit Factory & Gravity.
 

Using crt.bi for opening files

Started by ninogenio, April 04, 2007

Previous topic - Next topic

0 Members and 0 Guests are viewing this topic.

ninogenio

just wondering if anyone can see where im going wrong here as ive not used the crt file funcs in freebasic before.


#Include Once "Crt.bi"

Dim Shared As File PTR Handle
Handle = Fopen("BadGuyTMap1.SGM", "r")
Dim Shared As ZString PTR FileIn

Dim Shared As Integer size
Size=Sizeof(Handle)

filein = malloc (size+1)
for x = 0 to size
          Filein[x]=fgetc(handle)
next
fclose(handle)

print FileIn

sleep
Challenge Trophies Won:

Stonemonkey

I've not used it either but if handle is a pointer, won't sizeof(handle) return 4, as a pointer is 4 bytes and your code will read the first 5 bytes from the file?

ninogenio

ahh yes your quite right so i take it the file size is the number of elements in my txt file*4.

does anyone have a decent filesize function lying around where i could go filesize = sizeoffile(Handle).
Challenge Trophies Won:

Stonemonkey

what about writing the size of the file or size of the map into the start of your file? then when you open it for reading you can read how much data it contains.

ninogenio

yeah for sure that would work i just like clean code that can dynamically resize a variable to whatever is needed at that time.

theres still something not quite right with the abouve even with the size amended when i try to print the contents of filein i just get garbage im trying to print it like this printf("%s", Filein).
Challenge Trophies Won:

Stonemonkey

you can read the size from the file first then allocate however much memory you're going to need. unless there's some other way like LOF that's in the inbuilt FB file handling that'll return the length of a file.

ninogenio

not sure but i think Lof works only when you open the file using fbs commands im thinking it might be possible to create a getfilesize function that records current position moves to the start of the file then loops through the file 4 bytes at a time till it hits Eof then puts the file position back to where ever it was when the function was called ill try that out but i still have the problem of why its not reading properly?
Challenge Trophies Won:

Stonemonkey


Jim

To get the length you can try...

fseek(handle, 0, SEEK_END);
length = ftell(handle);
fseek(handle, 0, SEEK_SET);


Then, instead of reading every byte one at a time,

fread(filein, 1, size, handle);


I think you want to be opening your file in "rb" not "r" mode with fopen too.

Jim
Challenge Trophies Won:

ninogenio

works like a charm now cheers guys.

it works in both r and rb modes.


#Include Once "Crt.bi"

Dim Shared As File PTR Handle
Handle = Fopen("BadGuyTMap1.SGM", "rb")
Dim Shared As ZString PTR FileIn

Dim Shared As Integer size
Fseek(Handle, 0, SEEK_END)
Size = Ftell(Handle)
Fseek(Handle, 0, SEEK_SET)

Filein = Malloc(Size+1)
Fread(Filein, 1, Size, Handle)
Fclose(Handle)

Printf("%s", Filein)

sleep

Challenge Trophies Won:

Jim

If you use "r" mode for binary files, the CRT is allowed to do line-ending translations (usually between DOS and Unix (0x0d 0x0a -> 0x0a)) which will break your file.  Use "rb" for binary.  Like you say it probably works OK in "r" mode, and on most Unixes there's no difference between the two, but you should do it right :)

Jim
Challenge Trophies Won:

ninogenio

you learn something new every day ta jim.
Challenge Trophies Won:

rdc

file.bi contains several functions that operate on files that are a bit easier to use:


#include "file.bi"

dim as integer fh, i, fsize
dim as byte ptr fl

fsize = filelen("filename.ext")
fl = callocate(fsize)
fh = freefile
open "filename.ext" for binary as #fh
get #fh,, *fl, fsize
close fh

for i = 0 to fsize - 1
    print fl[i]
next
sleep


ninogenio

yeah ive used the fb commands before but i dont like them i think the crt ones are more versitile and then if my stuff is ever getting ported to c its should be a dodle.
Challenge Trophies Won:

ninogenio

just wonderind what the best way of reading a line in using sscanf would be my line is a has 150 numbers and 150 , s i want to stip the commas out and dump the numbers in an array i know how todo this on small lines using sscanf but not big ones.
Challenge Trophies Won:

Jim

untested

dim numbers (256) as integer
for x = 0 to 149
fscanf(handle, "%d,", @numbers(x))
next

Check it doesn't miss out the last number.
fgets/sscanf are hard to use here because you want to step over each number as you eat it up.

Jim
Challenge Trophies Won:

ninogenio

cool yeah it picks up the last number because its a file function will it automatically move onto the next line when it hits '\0' so calling the same would result in it reading a new line?
Challenge Trophies Won:

ninogenio

just tested and it does move down lines also. i must say its amazing how simple it is to parse through files with crt it looks a bit daunting at first but its so much more flexable.
Challenge Trophies Won:

Jim

Quotebecause its a file function will it automatically move onto the next line when it hits '\0' so calling the same would result in it reading a new line?
No, but the fscanf will hit the line end and see it doesn't match the "%d," and so stop anyway.

Jim
Challenge Trophies Won:

ninogenio

ahh right ive noticed something weird in fb using printf it doesnt do anything with \n it just prints it as part of the string.
Challenge Trophies Won: