Simple File I/O

New to FreeBASIC? Post your questions here.
Post Reply
Halifax
Posts: 65
Joined: Nov 04, 2005 1:30

Simple File I/O

Post by Halifax »

Simple help needed. I'm looking to store data in a file.

I'm gonna need to copy several arrays of simple integers.

Here's what I was able to cobble together from the wiki.

Code: Select all

'// To Save Data
type MapData
   ParallaxIdent As Integer '// simple ID for which parallax bk to use
   OverlayIdent As Integer
   TerrainLayer(1 to 40,1 to 30) as integer
   ObjectLayer(1 to 40,1 to 30) as integer
   EventLayer(1 To 160, 1 To 120) As Integer
end Type

Dim MD(1 To 10) As MapData, SimInc as integer

f = FreeFile

Open "filename.map" For Binary As #f

If Err>0 Then Print "Error opening the file":End

For SimInc = 1 To 10
	Put #f, ,MD(1).ParallaxIdent
	Put #f, ,MD(1).OverlayIdent
	Put #f, ,MD(1).TerrainLayer()
	Put #f, ,MD(1).ObjectLayer()
	Put #f, ,MD(1).EventLayer()
Next SimInc

Close

End
So -

I don't have to specify where in the file to write because it will auto increment?

I don't have to specify array size, etc?

I'll have to read this stuff back into the same arrays I used to write, but I don't think I'll ever have to read out of order, should be a full write/read every time I access file.

Any tips, corrections?
Halifax
Posts: 65
Joined: Nov 04, 2005 1:30

Post by Halifax »

Here's what I've come up with.

I have to specify each data piece when getting and putting. Also, this didn't work when I used input/output modes.

Code: Select all

'// Storing Data
randomize timer
screen 18,24,,0      '// 640,480, high bit depth,,windowed/full screen

Function RndNum(a As Integer, b As Integer)
    
    RndNum = Cint(Rnd*(b - a) + a)
    
End Function

type MapData
	ParallaxIdent As Integer '// simple ID for which parallax bk to use
	OverlayIdent As Integer
   TerrainLayer(1 to 40,1 to 30) as integer
   ObjectLayer(1 to 40,1 to 30) as integer
   EventLayer(1 To 160, 1 To 120) As Integer
end type

Dim Shared MD(1 To 10) As MapData

dim Path as String = "c:\resources\" 

For i = 1 To 10
	With MD(i)
		.ParallaxIdent = RndNum(1,10)
		.OverlayIdent = RndNum(1,10)
		For x = 1 To 40
			For y = 1 To 30
				.TerrainLayer(x,y) = RndNum(1,255)
				.ObjectLayer(x,y) = RndNum(1,255)
			Next
		Next
		For x = 1 To 160
			For y = 1 To 120
				.EventLayer(x,y) = RndNum(1,1000)
			Next
		Next
	End With
Next

f = FreeFile
Open Path + "filename.map" For Binary As #f

For i = 1 To 10
	Put #f, ,MD(i).ParallaxIdent
	Put #f, ,MD(i).OverlayIdent
	For x = 1 To 40
			For y = 1 To 30
				Put #f, ,MD(i).TerrainLayer(x,y)
				put #f, ,MD(i).ObjectLayer(x,y)
			Next 
	Next
	For x = 1 To 160
		For y = 1 To 120
			Put #f, ,MD(i).EventLayer(x,y)
		Next
	Next
Next

Close

For i = 1 To 10
	With MD(i)
		.ParallaxIdent = 0
		.OverlayIdent = 0
		For x = 1 To 40
			For y = 1 To 30
				.TerrainLayer(x,y) = 0
				.ObjectLayer(x,y) = 0
			Next
		Next
		For x = 1 To 160
			For y = 1 To 120
				.EventLayer(x,y) = 0
			Next
		Next
	End With
Next

Print "data erased"
Print MD(1).ParallaxIdent
Print MD(7).ParallaxIdent

f = FreeFile
Open Path + "filename.map" For binary As #f

For i = 1 To 10
	Get #f, ,MD(i).ParallaxIdent
	Get #f, ,MD(i).OverlayIdent
	For x = 1 To 40
			For y = 1 To 30
				Get #f, ,MD(i).TerrainLayer(x,y)
				Get #f, ,MD(i).ObjectLayer(x,y)
			Next 
	Next
	For x = 1 To 160
		For y = 1 To 120
			Get #f, ,MD(i).EventLayer(x,y)
		Next
	Next
Next
Close

Print "data retrieved"
Print MD(1).ParallaxIdent
Print MD(7).TerrainLayer(10,10)

sleep

End
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Post by MichaelW »

Opening the file for RANDOM will allow you to get or put the entire array with a single statement. On my system, compared to the first code you posted, the random access method is ~5x slower.
Last edited by MichaelW on Aug 23, 2009 7:30, edited 1 time in total.
KristopherWindsor
Posts: 2428
Joined: Jul 19, 2006 19:17
Location: Sunnyvale, CA
Contact:

Post by KristopherWindsor »

This is somewhat irrelevant, but your random function is wrong. ;)
(CInt() rounds to the nearest integer; my function uses Int() to round down to the nearest integer, and the actual cast from double to integer is implicit.)

Code: Select all

Function RndNum(a As Integer, b As Integer) As Integer
  RndNum = Cint(Rnd*(b - a) + a)
End Function

Dim As Integer t(2 To 4)

For i As Integer = 1 To 1E6
  t(rndnum(2, 4)) += 1
Next i

For i As Integer = 2 To 4
  Print i, Cint(t(i) \ 1E4) & "%"
Next i

Sleep()



? : ?



Function Rnd2(a As Integer, b As Integer) As Integer
  Return Int(Rnd * (b - a + 1) + a)
End Function

t(2) = 0: t(3) = 0: t(4) = 0

For i As Integer = 1 To 1E6
  t(rnd2(2, 4)) += 1
Next i

For i As Integer = 2 To 4
  Print i, Cint(t(i) \ 1E4) & "%"
Next i

Sleep()
Halifax
Posts: 65
Joined: Nov 04, 2005 1:30

Post by Halifax »

Swapped my random function over to yours. Don't have anything up in the program yet to test it, but I've always relied on blind trust.

Thnx, these small corrections are exactly what I'm looking for.
Post Reply