Pages

11. Reading and Writing Integers from a File

A recent comment to Post 6 asked: I have a FreeBASIC program which writes just over 100,000 integers to a file. I would like to see an example of how to read such a file.

In this post we will create a file with 100,000 random integers then show how we can read them back and and manipulate them.

Let's start by writing our header:


/'
======================
Integer File read in FreeBasic
Franktic
25 July 2017
======================
'/


Next we will declare some variables.  I was taught to always initialise variables at declaration and, as all the variables are integers, let's set them all to zero.  

Dim As Integer myFile = 0  ' file handle
Dim As Integer x = 0       ' loop counter
Dim As Integer iSum = 0    ' will hold sum of integers selected
Dim As Integer iBig = 0    ' will hold the largest integer of those selected
Dim As Integer iSmall = 0  ' will hold the smallest integer of those selected

We will also declare an array to hold the integers we read back from the file.  Note, the array has to have enough items declared to hold all the integers read back.  If we declare our array to go from 1 to 1000 and we try and store more than 1000 items the program will crash.

Dim As Integer aInt( 1 To 100000)

As we saw in the two 'Fundamental' posts, we need to generate a file handle using the FreeFile() command and assign it to our myFile variable.  We can then Open the file for Output since we want to write the integers.

/' Generate Integers and write to file '/ 
myFile = FreeFile()
Open "test.txt" for Output as #myFile

This next section of code initialises the randomize command then enters a loop that will cycle 100,000 times.  With each pass it prints the loop number so we know the program is working and generates a random number between 1 and 100 (like throwing a 100 sided dice, this rnd function is explained in a previous post) which it writes directly into the file we created above.  At the end of for...next loop we close the file.

Randomize, 1

For x = 1 To 100000
'show where we are up to
Print Str(x)
Print #myFile, Str(Int(Rnd*100)+1)
Next

Close #myFile

We add two lines to tell us that the writing has completed.  The Sleep command waits for the user to press a key before it continues.  Adding a break such as this in a program is useful for finding errors (debugging).  Once you are happy the program is working correctly you can get rid of these lines or simply comment them out.

Print "Integer file written.  Press any key to continue."
Sleep

Now to read the integers back.  First of we clear the screen with the Cls command and open the file for Input - we are reading, input, from the file - not writing, output.  Using the Input command in the for loop we read each integer directly into our integer array declared earlier. And, like before, we close the file once we are done.

Cls
' Read Integers from file into array aInt()
Open "test.txt" for Input as #myFile

For x = 1 to 100000
Input #myFile, aInt(x)
Next

Close #myFile

To give an example of what we can do with the array of random integers we have just read, we will focus on the first 10 integers in the file, now in the array.  You can choose a different set of integers or the entire 100,000 if you want.  Let's  calculate the sum of the 10 integers, then find the largest integer and the smallest integer.

First off we initialise the iBig and iSmall variables to the first integer in our array.

iBig = aInt(1)
iSmall = aInt(1)

The for...next loop will cycle 10 times and add the current array integer to the iSum variable.  At the end of the loop we will have added all 10 array integers to iSum and have our sum.

The statement starting with If iBig compares the contents of iBig with the current array contents.  If iBig is smaller, meaning the array contents is bigger, then we set iBig to the larger integer.  If iBig is the same size or larger then this bit of code is skipped.  At the end of the for...next loop iBig will hold the largest integer in the set we selected.

The statement starting with If iSmall performs a very similar operation however, at the end of the for...next loop,  it will contain the smallest integer of the set we selected.

For x = 1 To 10
iSum = iSum + aInt(x)
If iBig < aInt(x)Then
iBig = aInt(x)
EndIf
If iSmall > aInt(x)Then
iSmall = aInt(x)
EndIf
Next

Now we have a small section that displays what we have done and...that's all folks.

Print "The sum of the first 10 numbers read is " + Str(iSum)
Print "The largest of the first 10 numbers read is " + Str(iBig)
Print "The smallest of the first 10 numbers read is " + Str(iSmall)

Sleep
End

You can cut and paste each of the sections of code above into your FreeBasic editor and run it or,  better still, type it out by hand.  Typing out by hand actually gives you a bit of practice in using the editor and, if you make a typing mistake, it will help you learn to read your code and find errors.  If you type it you may also be encouraged to try modify the code to see the effect of your changes.

When I wrote this short program I didn't want to wait for 100,000 integers to be generated (although in the end it didn't take terribly long) so I started with generating 100.  I set up the array and the loops to deal with 100 integers.  Then, when I modified the program so that it would generate 100,000 integers I changed the loops but forgot the array dimension.  I could not understand why the program was crashing after it generated 100 integers. This was a simple bug that was easily fixed but one that I will look out for in future programs.

Anyhow, I hope this post has been useful.  Please feel free to leave a comment and see you in the next post.

1 comment:

  1. St_W on the FreeBASIC forum makes good point about the use of integer in the example above.

    Integer may be not an optimal choice here, because it has a different size depending on the bitness of the system/compiler. Integer is especially tricky because it is 32-bits on a 32-bit platform and 64-bits on a 64-bit platform. That is why one should be very careful when using Integer. If you want a fixed-size data type (like for writing something to a file, which should not be platform dependent usually) use e.g. Long or (better readable) Integer<32>.

    Thanks for the comment and the explanation.

    ReplyDelete