0

I'm doing a program to manage a clinic, but I'm having a problem. I need to read a binary file with the information from the Doctors. The information is name, code and telephone. They are inserted by the user.

How can I printf that info separately. For example:

Name: John Cruz
Code: JC
Telephone: 90832324

I'm trying to use

typedef struct {
  char code[10];
  char name[100];
  int telephone;
} DOCTOR;


int newDoctor() {//This is the function that create the binary file
  DOCTOR d;
  FILE *fp;
  fp = fopen("Doctors.dat","wb");

  if(fp==NULL) {
    printf("Error!");
        return -1;
  }

  printf("Code\n");
  fflush(stdin);
  gets(d.code);
  printf("Name\n");
  gets(d.name);
  printf("Telephone\n");
  scanf("%d",&d.telephone);
  fprintf(fp,"%s;%s;%d",d.code,d.name, d.telephone);
  fclose(fp);
}

//And to open
FILE* fp;
fp=fopen("Doctors.dat","rb");

while(!EOF(fp)) {
  fgets(line, 100, fp);
  printf("%s",line);
}

Just to see the line but it's not working, and how i can separate the info?

Regards

4
  • You'd need to know the binary format of the file. Commented May 3, 2011 at 17:40
  • You are opening it just fine. It's the reading that is the problem- reference my answer. Commented May 3, 2011 at 17:43
  • Like Brian said you need to know what format/structure the information is in. Then you can make a struct after that format/structure and then parse the file and put the information in a series of structs to have everything structured and easy to access. Commented May 3, 2011 at 17:43
  • why do you think that fprintf(fp,"%s;%s;%d",d.code,d.name, d.telephone); will make file "binary". Also, check return value after fgets() call. Commented May 3, 2011 at 18:13

3 Answers 3

1

fgets assumes that the data is ascii strings. For binary data you need to know the binary format and read the data into the appropriate data structures.

Sign up to request clarification or add additional context in comments.

2 Comments

user736592, "C" can save files in a nearly infinite number of binary formats. Knowing that it is a binary file is not enough, you have to find out what the format is. The best way to do that is to go to whatever person or program generated the file and find out what they did. If it was generated by a program that you don't have the source code for, you will have to ask the program's creator.
@user - C doesn't save a "format". Whatever code that is writing that file is writing it in a user defined binary format. You need to know what that format is. If you don't know that, and don't have access to the code that's writing it, you've got a not easy task of reverse engineering ahead of you.
1

You must know the format the binary is in, such as if you serialized a previous struct then you can read it into a struct of the same type:

typedef struct
{
   int stuff;
   double things;
} myStruct;

myStruct writeMe = {5, 20.5};

FILE* fp;
fp = fopen("Doctores.dat","wb");
if (fp == NULL) { fputs ("File error", stderr); exit(EXIT_ERROR); }

fwrite(writeMe, 1, sizeof(writeMe), fp);
fclose(fp);

Then later to read:

myStruct readMe;

FILE* fp2;
fp2 = fopen("Doctores.dat","rb");
if (fp2 == NULL) { fputs ("File error", stderr); exit(EXIT_ERROR); }

fread(readMe, 1, sizeof(readMe), fp2);
fclose(fp2);

printf("my int: %i\nmy double: %f", readMe.stuff, readMe.things);

Hope this helps

2 Comments

The problem with this solution is that the size of a struct may not be equal to the sum of the size of its members. The compiler is allowed to add "padding" bytes between members. A higher quality solution is to write the individual members not the entire structure.
true, it would be more portable and better to read/write each member seperately. Alternatively you can also use compiler flags to prevent padding, such as __attribute__((packed)) on gcc and doing a #pragma push/pop on VC++ and others (link)
1

There are at least two issues here: file & data format and reading a binary file. File format is how the information is organized within the file. Binary reading involves reading the file without any translations.

File and Data Format

For text fields, you need to know the following:

  • Fixed or variable length field.
  • Maximum field width.
  • Representation (null terminated, fixed length, padded, preceded by length of string, etc.)

You can't assume anything. Get the format in writing. If you don't understand the writing, have the original author rewrite the documentation or explain it to you.

For integral numeric fields you need to know the following:

  • Size of number, in bytes.
  • Endianness: Is first byte the Most Significant (MSB) or Least significant (LSB)?
  • Signed or Unsigned
  • One's complement or two's complement

Numbers can range from 1 "byte" to at least 8 bytes, depending on the platform. If your platform has a native 32-bit integer but the format is 16-bit, your program will read 16 extra bits from the next field. Not good; bad, very bad.

For floating point: you need to know the representation. The are many ways to represent a floating point number. Floating point numbers can very in size also. Some platforms use 32-bits, while others use 80 bits or more. Again, assume nothing.

Binary Reading

There are no magic methods in the C and C++ libraries to read your structure correctly in one function call; you will have to assemble the fields yourself. One thorn or bump is the fact that compilers may insert "padding" bytes between fields. This is compiler dependent and the quantity of padding bytes is not standard. It is also known as alignment.

Binary reading involves using fread or std::istream::read. The common method is to allocate a buffer, read a block of data into the buffer, then compose the structures from that buffer based on the file format specification.

Summary

Before reading a binary stream of data, you will need a format specification. There are various ways to represent data and internal data representation varies by platform. Binary data is best read into a buffer, then program structures and variables can be built from the buffer.

Textual representations are simpler to input. If possible, request that the creator of the data file use textual representations of the data. Field separators are useful too. A language like XML helps organize the textual data and provides the format in the data file (but may be too verbose for some applications).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.