views:

920

answers:

6

Hello,

I have a binary file with variable length record that looks about like this:

12  economic10
13  science5
14  music1 
15  physics9
16  chemistry9
17  history2 
18  anatomy7 
19  physiology7
20  literature3
21  fiction3
16  chemistry7
14  music10 
20  literature1

The name of the course is the only variable length record in the file, the first number is the code of the course and it can be a number between 1 and 9999 and the 2nd number is the department and it can be between 1 and 10. As you see in the file there is no space between the name of the course and the department number.

The question is how can I read from the binary file? There is no field in the file to tell me what is the size of the string which is the course name.. I can read the first int (course id) fine, but how do I know what is the size of the name of the course?

Thanks in advance,

Greg

A: 

To read variable length records, you should use some sort of convention. For example, a special characters that indicates the end of a record. Inside every record, you could use a another special character indicating end of field.

DO_READ    read from file
           is END_OF_RECORD char present?
           yes: GOTO DO_PROCESS
           no : GOTO DO_READ

DO_PROCESS read into buffer
           is END_OF_FILE mark present?
           yes: GOTO DOSOMETHINGWITHIT
           no:  GOTO DO_PROCESS
Tom
Ok, lets say that "\n" is the end of the record. Meaning that every record begins in new line. How can I read it then?
Are you talking about a text file or a binary file? Your example looks like text, and adding a newline at the end of record sounds like text. If you want to delimit a binary string, why not use a null character ('\0'), especially if you are using C?
KeyserSoze
The teacher told us that the binary file will look like this, she cant give us the actual binary file because we wont be able to read it ofcourse..so I can't really change how it will look in the beginning with all the records. I need to read each record somehow from the file..very strange I agree...
A: 

You'd need to know how the file was written out in the first place.

dirkgently
A: 

If there is a one to one correspondence between course code and course name (including department code), you can deduce the size of the course name from its code, with a predefined table somewhere in the code or in a configuration file.

If not, the main problem I see is to discriminate things like music1 and music10.

mouviciel
The problem is I dont know what is the size of the string of the course name so how can I read it? It can be 5 chars and it can be 20 chars..I know that the record ends with "\n", does that help me?
Yes! It does help you!!
Albert
+1  A: 

As others have said this looks a lot like text, so a text parsing approach is likely to be the right way to go. Since this is homework, I'm not going to code it out for you, but here's the general approach I'd take:

  • Using fscanf, read the course code, and a combined string with the name and department code.
  • Starting from the end of the combined string, go backwards until you find the first non-digit. This is end the of the course name.
  • Read the integer starting just beyond the end of the course name (ie, the last digit we find scanning backwards).
  • Replace the first character of that integer's part of the string with a NUL ('\0') - this terminates the combined string immediately after the course name. So all we have left in the combined string is the course name, and we have the course code and department code in integer variables.
  • Repeat for the next line.
bdonlan
+2  A: 

Use fscanf() with the format string "%u %[a-z]%u".

Here's a complete example program:

#include <stdio.h>

#define NAME_MAX 64

int main(int argc, char ** argv)
{
    FILE * file = fopen("foo.txt", "rb");
    unsigned int course, department;
    char name[NAME_MAX];

    while(fscanf(file, "%u %[a-z]%u", &course, name, &department) != EOF)
    {
     // do stuff with records
     printf("%u-%u %s\n", department, course, name);
    }

    fclose(file);

    return 0;
}
Christoph
A: 
mrwes