0

I use fwrite to write element by element of my structure but I can't understand why in my binary file there are saved more information(different direcory paths) except only the information from the structure? I apply only the way i write in my binary file. Also i tried to wrtite the same structure in new text file and there is no problem like this in the binary.

struct student{
  int ID;
  char name[30];
  char secondName[30];
  double mark;
}typedef student;


int main()
{
  FILE *fp;

  struct student *student;
  int numberOfStudents;
  char *filename;
  int numberOfcharacter;

  student = (struct student *) malloc(numberOfStudents * sizeof(struct 
                                student));


  printf("Enter the number of character of the filename: ");
  scanf("%d", &numberOfcharacter);

  filename = (char *) malloc(numberOfcharacter * sizeof(char));

  if(filename == NULL)
    {
      perror("Memory error! ");
      exit(23);
    }

  fflush(stdin);

  printf("Write the name of your bin file: ");
  scanf("%s", filename);

  if((fp = fopen(filename, "wb")) == NULL)
    {
      perror("Error in creating the file! ");
      exit(2);
    }

  for(int i=0; i<numberOfStudents; i++) {

    int lenOfName = strlen((student+i)->name);
    int lenOfSecondName = strlen((student+i)->secondName);

    if(fwrite(&(student+i)->ID, sizeof(struct student), 1, fp) != 1)
      {
    perror("Error in writing! ");
    break;
      }

    if(fwrite(&lenOfName, sizeof(int), 1, fp) != 1)
      {
    perror("Error in writing! ");
    break;
      }

    if(fwrite((student+i)->name, sizeof(struct student), lenOfName, fp) 
       != lenOfName)
      {
    perror("Error in writing! ");
    break;
      }

    if(fwrite(&lenOfSecondName, sizeof(int), 1, fp) != 1)
      {
    perror("Error in writing! ");
    break;
      }

    if(fwrite((student+i)->secondName, sizeof(struct student), 
          lenOfSecondName, fp) != lenOfSecondName)
      {
    perror("Error in writing! ");
    break;
      }

    if(fwrite(&(student+i)->mark, sizeof(struct student), 1, fp) != 1)
      {
    perror("Error in writing! ");
    break;
      }

  }

  free(filename);
  free(student);
  fclose(fp);
alinsoar
  • 15,386
  • 4
  • 57
  • 74
  • 1
    Three things: First [don't cast the result of `malloc`](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/). Secondly, passing an input-only stream (like `stdin`) to `fflush` is explicitly mentioned in the C specification as *undefined behavior*. Thirdly, don't forget to remind the user to include space for the string null-terminator when you ask for the length of the filename. – Some programmer dude Apr 09 '19 at 13:02
  • 2
    You are writing the entire struct to the file. So all 30 bytes of `name` and all 30 of `secondName` get written, no matter what the length of the string is. – 001 Apr 09 '19 at 13:03
  • 1
    A few other things: For any pointer or array `p` and index `i`, the expression `*(p + i)` is *exactly* equal to `p[i]`. Which means `(student+i)->name` is exactly equal to `student[i].name`. The latter is usually easier to read and understand (and less to write). Then you loop over the `student` "array" and using its data *when it's not initialized!* – Some programmer dude Apr 09 '19 at 13:04
  • 3
    And there are many other problems, like writing the individual members of the structure, but always passing `sizeof(struct student)` as the size. Why don't you write the complete array at once? Like `fwrite(student, sizeof student[0], numberOfStudents, fp)` (although currently it would just write "garbage" since you don't initialize the structures in the array). – Some programmer dude Apr 09 '19 at 13:07
  • 1
    Another problem: `numberOfStudents` is not initialized, so its different use will cause undefined behavior. (used in `malloc` and `for` loop) – Mathieu Apr 09 '19 at 13:14
  • 1
    You should never use `scanf("%s"...)` nor `gets(...)`. This allows a buffer overflow, which might cause your problem, you should add the (fixed) size of the buffer between `%` and `s`: `scanf("%30s",...)`. Or you can use `read(stdin, ...)` with a size parameter. `scanf("%s", filename);` becomes `read(stdin, filename, numberOfCharacter);`. – cmdLP Apr 09 '19 at 13:19

0 Answers0