Computer Science Canada

Reading Records from BIN file

Author:  araisbec [ Sun Mar 14, 2010 5:31 pm ]
Post subject:  Reading Records from BIN file

This problem has been racking my brain for the last three days. The code I am required to write must store records with the following structure:
code:

typedef struct{
char *  name;
char *  address;
short   addressLength, nameLength;
double  phoneNumber;
} employeeRecord;

The program stores these records to a bin file using fwrite, storing the record, followed by the strings for both the name and address fields (hence why the lengths are stored in the struct, to make seeking through the data possible). I am 99% sure I am storing the information right, however my program cannot find any record but the first in the file when I search by record number (first record is #0, 1, 2 etc.). Here is my function that searches by record number:
code:

void byNumber(FILE *fp, employeeRecord record){

        int found = 0, number = 0, cntr = 0;
        printf ("Enter record number: ");
        scanf ("%d", &number);
        fseek (fp, 0, SEEK_SET);
        do{
                fread (&record, sizeof record, 1, fp);
                record.name = malloc (sizeof (char)*record.nameLength);
                record.address = malloc (sizeof (char)*record.addressLength);
                fread (record.name, 1, record.nameLength, fp);
                fread (record.address, 1, record.addressLength, fp);
                if (feof (fp)){
                        break;
                }
                if (cntr == number){
                        printf ("RECORD FOUND\n\nName: %s\nAddress: %s\nPhone number: %lf\n\n", record.name, record.address, record.phoneNumber);
                        found = 1;
                }
                cntr += 1;
                fseek (fp, (sizeof(record)+(sizeof(char)*record.nameLength)+(sizeof(char)*record.addressLength))*(cntr+1), SEEK_SET);
        }while (1==1);
        if (found == 0){
                printf ("RECORD NOT FOUND\n\n");
        }
}

I'm very sure that the problem lies in that function somewhere, I will also add that I am opening the file in "a+b" mode at the start of execution and then closing it upon termination of the code. Any ideas?

Author:  araisbec [ Mon Mar 15, 2010 3:30 pm ]
Post subject:  RE:Reading Records from BIN file

Anything?

Author:  DemonWasp [ Mon Mar 15, 2010 4:29 pm ]
Post subject:  RE:Reading Records from BIN file

That's an odd use of fseek, given as you seem to be iterating through the file.

What seems most likely is a mismatch between how you're recording the employeeRecord and how you're reading it. Can we see the code for writing this file?

Author:  DtY [ Mon Mar 15, 2010 8:50 pm ]
Post subject:  RE:Reading Records from BIN file

So you have a problem searching BINs for records?

(sorry)

Would you be allowed to make the strings fixed size? That would make each record a fixed length, making the problem a lot easier.

Author:  araisbec [ Tue Mar 16, 2010 2:41 pm ]
Post subject:  Re: Reading Records from BIN file

Alright, here is the code for writing the records to the bin file:
code:

void newRecord (FILE *fp, employeeRecord record){
       
        char c = getchar ();      // I used a scanf prior to calling this function and there was still a newline character in the stdin buffer
        printf ("Enter name: ");
        record.name = malloc (sizeof (char)*20);
        gets (record.name);
       
        printf ("Enter address: ");
        record.address = malloc (sizeof (char)*30);
        gets (record.address);
       
        printf ("Enter telephone number: ");
        scanf ("%lf", &record.phoneNumber);
       
        record.addressLength = strlen (record.address);
        record.nameLength = strlen (record.name);

        fseek (fp, 0, SEEK_END);
        fwrite (&record, sizeof(record), 1, fp);
        fwrite (record.name, sizeof(char), record.nameLength, fp);
        fwrite (record.address, sizeof(char), record.addressLength, fp);

        printf ("INFORMATION SAVED %d", ftell (fp));
}

And no, we must store each string as its exact length, reading them in after the records and then dynamically allocating them memory and linking that memory to the pointers for them in the record. I think the instructor wants us to practise being super efficient with memory or somthing.

Author:  DemonWasp [ Tue Mar 16, 2010 3:11 pm ]
Post subject:  RE:Reading Records from BIN file

You don't appear to be storing or reading nameLength or addressLength. Without knowing how many characters to read for each string, you're lost. You almost certainly want to length-prefix your strings (write the string's length, then the string itself).


: