Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Need some Qbasic help me Random Files/ Records (Please)
#11
Thanks for the help, I will try that, it may actually make printing my records MUCH easier.

I had some trouble attempting the to implement the code you provided yeasterday. Unfortunately I don't have my exact code here (i'll post it tommorow, as I don't have my disk), but essentially this is what happens.



edit: this isn't all I put, it's just what I can remember
Code:
' game is the name of my random file
Erase game

ERROR: Array not Defined

And when I try to execute a FOR NEXT LOOP to print all my data
Code:
FOR X = 1 to final
GET #1, final, game
PRINT title.game
NEXT X

I just get an infinite loop that flashes my data on the screen, repeatedly

When I attempt to delete a record and use a

Code:
Do Until EOF(1)
'code goes here
LOOP
I just get an infinite loop that goes nowhere. It's really hard to explain and I will try to get my source tommorow

One more thing, I am currently working on having my data placed into the record sequenced location number (so the first record will go into number 1, second in 2 etc), but I am unsure on how to do it.

BTW, incase you're wondering, by helping me you aren't doing my work for me (you are just helping my out a lot Wink )[/code]


EDIT:
Just so you know what I have to do, I need to do the following
To get a C mark
Create a File storage program to store records
Be able to add records
Be able to delete records
Be able to modify records

To get a B mark
Be able to sort the array by two different criteria (i.e. by title, or my genre)

To get a A mark
Be able to use a binary search, a sequential search and a bunch of other stuff.

This is the design I came up with
Add records - standard random filage

Delete Records- Print my records, with the record number, and give them an option of what they want to delete

Modify Records- Print my records with the record number, and give them an option of what record they want to replace

Sorting Records- Have the records set up in a sequential location (1, 2, 3, 4, 5 etc) and use a fornext loop to place them into an array.
i.e.
Code:
FOR X = 1 to totalrecords
GET #1, X, Game
             Let Title.Game = Title(x)
NEXT X

The rest- use my array to do some basic sorting and searching.


I know exactly what to do, I just need to be able to know how to do the following.

1. Delete a record
2. Have my records located sequentially (which will then allow my to easily print it, assign it to arrays and stuff)
I can figure everything else out (due to the help you gave me Smile )


Smile

When I was thinking about it earlier I came to the conclusion that blank records didn't really matter as I would just get the program to ignore it.
Reply
#12
Sorry. I think I gave you misinformation about the ERASE command. I'll cover that in this post.

==============================================

Alright, let's go over some quick terms, here:

1. the DATA FILE is literally the file on your hard drive that is storing the data, for example "records.dat"

2. the DATA TYPE is the way in which data gets saved to a varible. STRING is a data type. So is INTEGER or LONG INTEGER. For this project, you are making your own data type, which is called a USER-DEFINED DATA TYPE. You do this by using the TYPE command, as follows:

Code:
TYPE RecordType
  FName as STRING * 20
  LName as STRING * 20
  Age as INTEGER
END TYPE

This will make a user-defined data type called "RecordType" so that you can now make variables of this type. You make variables of this type by using the DIM command (or SHARED, or COMMON, but let's use DIM for this program).

Code:
DIM CurrentRecord AS RecordType

There. Now we've created a variable called CurrentRecord that has elements defined in RecordType. Each element can be accessed by {variable name}.{type element}, for example: CurrentRecord.FName or CurrentRecord.Age

You can also make an array in which each element of the array is a "record" that looks like your defined data type:

Code:
DIM RecordArray(1 to 10) AS RecordType

This will give you an array of 10 records, each one with the three elements defined in RecordType. You can access them by {array name}(location in array).{type element}, for example: RecordArray(2).Age or RecordArray(1).LName

So now let's look at the data file, "records.dat". When you use a RANDOM file (usually when you're dealing with records), you have to define the SIZE of the record each time you open it, so that it knows where one record ends and the next record begins. This is done with the LEN command in the OPEN line:

OPEN {filename} FOR {access mode} AS #{filenumber} LEN = {recordlength}

so, for example:

Code:
OPEN "records.dat" FOR RANDOM AS #1 LEN = LEN(CurrentRecord)

This will open the file "records.dat" for random access (read/write) as file number 1 (so it can be quickly referred to as #1 later). The LEN = LEN(CurrentRecord) mean that you're telling the program that each record in "records.dat" is the SAME EXACT SIZE as the record called "CurrentRecord", which is a variable you've defined earlier. This way, when you tell the program to get the 5th record from "records.dat", it knows where it starts.

Now that we have that all clear, I hope, let's take a look at some commands.

ERASE is a command that clears all values in an array. If you had an array of integers "x(1 to 10)", and you did this:

Code:
ERASE x

it would set x(1) = 0, x(2) = 0, and so forth. If you had a string array MyName$(1 to 3), and you did this:

Code:
ERASE MyName$

it would set MyName$(1) = "", MyName$(2) = "", and so forth

it clears whatever array you pass it. Therefore, if you pass it a USER-DEFINED VARIABLE ARRAY (such as RecordArray, which we've already defined as being of type RecordType):

Code:
ERASE RecordArray

The result of this line will be that

RecordArray(1).FName = " "
RecordArray(1).LName = " "
RecordArray(1).Age = 0
RecordArray(2).FName = " "
RecordArray(2).LName = " "
RecordArray(2).Age = 0

And so forth. The elements that are defined (in RecordType) as STRING don't become null strings (""), but instead become filled with spaces, because the strings HAVE to be of length 20, since we declared that in the RecordType declaration. Record variables (user-defined, created with the TYPE statement) are fixed length, always.

When you're talking about "deleting a record" from your data file "records.dat", what we're REALLY doing is copying a BLANK record variable to that spot in the file. This is done by first getting a blank record, and then PUT-ting it into the file at the desired location with the PUT command:

Code:
INPUT "Enter the record # you wish to erase: ", DeleteMe
DIM BlankRecord AS RecordType
OPEN "records.dat" FOR RANDOM AS #1 LEN = LEN(BlankRecord)
  PUT #1, DeleteMe, BlankRecord
CLOSE #1

The PUT command in there puts the now-blank BlankRecord into spot DeleteMe, copying over whatever record previously existed in spot DeleteMe, thereby "deleting" that record from the file. Get it?

=============================================

So let's now take a look at the code you posted, and see where you went wrong:

Quote:' game is the name of my random file
Erase game

You don't use the ERASE command on your file. You don't use it on the data type, either. You ONLY use it on arrays. Let's see:

Code:
TYPE RecordType
  FName AS STRING * 20
  LName AS STRING * 20
  Age AS INTEGER
END TYPE

DIM CurrentRecord AS RecordType
DIM ArrayOfRecords(1 to 10) AS RecordType

Okay, the following commands would be valid:

Code:
ERASE ArrayOfRecords

This is an array, so it can be erased via ERASE.

These commands would not work:

ERASE CurrentRecord {this is a variable, not an array}
ERASE CurrentRecord.FName {this is a variable, not an array}
ERASE CurrentRecord.Age {this is a variable, not an array}
ERASE "records.dat" {this is a data file, not an array}
ERASE RecordType {this is a user-defined data type, not an array}
ERASE ArrayOfRecords(11).Age {this is an out-of-range variable}
ERASE RecordType.Age {RecordType is a user-defined data type, not an array. RecordType.Age is meaningless}

=============================================

Quote:FOR X = 1 to final
GET #1, final, game
PRINT title.game
NEXT X

In this piece of code, X is an integer starting at 1, in increasing by 1 until it reaches the value "final" (let's say final is 10 for the sake of this lesson)

Code:
final = 10
FOR x = 1 to final
  GET #1, x, CurrentRecord
  PRINT "First Name: "; CurrentRecord.FName
  PRINT "Last Name : "; CurrentRecord.LName
  PRINT "Age       :"; CurrentRecord.Age
NEXT x

This code would loop from 1 to final (10), and it would--during each loop--read CurrentRecord in from the data file at spots 1....10, and each time print out the elements of CurrentRecord.

===============================================

The EOF(file number) command is an integer that is either 0 or 1. It is, by default, 0. It becomes set to 1 when you attempt to GET a record from a random file that hasn't had anything PUT there (this will recult in EOF(#) = 1 *AND* a blank record in the variable you used "GET" with):

Code:
OPEN "records.dat" FOR RANDOM AS #1 LEN = LEN(CurrentRecord)
  Location = 0
  DO
    Location = Location + 1
    GET #1, Location, CurrentRecord
  LOOP UNTIL EOF(1)
CLOSE #1

This will keep reading records in from "records.dat" into the user-defined variable CurrentRecord, until it encounters a Location in the file that hasn't had a record PUT there. If you haven't PUT *anything* into "records.dat" (i.e. the file was just created), then this loop will only run one iteration, and the result will be:

Location = 1
EOF(1) = 1
CurrentRecord.FName = " "
CurrentRecord.LName = " "
CurrentRecord.Age = 0

And your data file will look like this:

Spot 0
- blank record
Spot 1
- blank record
Spot 2
- not yet used
Spot 3
- not yet used
Spot 4
- not yet used

And so forth. The record in Spot 1 will be blank, because when you tried to GET a record from it, it didn't have one to give you, so it made it blank, then gave you a blank one. This automatic "creation" of a blank record is what sets EOF(#) to one.

if you were to run that same loop AGAIN, on the same data file, it would read in the blank record from spot 1, then location would increase by one and it would try to read in a record from spot 2. since there isn't one there, it would make a blank one, load it into CurrentRecord, and set EOF(#) to 1, again.

Incidentally, EOF(#) resets to 0 when the file # gets CLOSEd.

I hope this post helps you out with your project.

*peace*

Meg.
Reply
#13
I editted this post because I figured a lot out.

I have passed the first section of the project and I figured out how to use a Delete. On Monday I am going to place all of my files into an array, and commence the sort.

Thanks Smile
Reply
#14
Glad to hear!

*peace*

Meg.
Reply
#15
I'm nearly done my program now, I just have some documentation and some fine tuning to do. I was wondering if you could help me out, though.

My first question is whether you knew how to write a string of programming that will automatically assign the location of a random file to the next available location. What I mean is:

The first time I create a record, location is 1
The second time I create a record, the location is 2
The third time I create a record, the location is 3
etc, etc

My second question is a really easy one. I was wondering how to limit the size of an Integer to two places, or get Qbasic to print only the first two digits of the number. I can easily do it with Print Using, but since I am nearly done the program, and I didn't use print using to output my data, I don't really want to waste the time going back fifty times and re-doing all of my output statements.

Is there a simple function to do this?
Reply
#16
To save a record to the first available blank location in a random access file, you use a DO..WHILE loop:

Code:
TYPE RecordType
  LName AS STRING * 20
  FName AS STRING * 20
  Age AS INTEGER
END TYPE

DIM CurrentRecord AS RecordType, BlankRecord AS RecordType

OPEN "records.dat" FOR RANDOM AS #1 LEN = LEN(CurrentRecord)
  Location = 0
  DO
    Location = Location + 1
    GET #1, Location, CurrentRecord
  LOOP UNTIL CurrentRecord.LName = BlankRecord.LName OR EOF(1)
  PRINT "Creating record at location "; Location
  INPUT "Enter Last Name: ", CurrentRecord.LName
  INPUT "Enter First Name: ", CurrentRecord.FName
  INPUT "Enter Age: ", CurrentRecord.Age
  PUT #1, Location, CurrentRecord
CLOSE #1

See? This code will check spot #1. If it's blank (or if a blank record is created when it tries to 'GET' from the file), then the loop ends, you input your info, and it gets saved to spot # "Location"

As far as outputting just two digits, I'd agree that using PRINT USING is your best bet. Just do a Search/Replace from the pull-down menu.

*peace*

Meg.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)