2

I am trying to write a function to take input from user in the form of a struct and insert it into a binary file. (of football results) the user is to enter teamA, teamB, goalsA and goalsB When I try to display what I have entered, I am not getting the correct result. What am I doing wrong? Code:

void addResult()
{
    struct matches match;
    char input[100];
    FILE * file1;

    file1 = fopen("matches.bin","rw+b");
    printf("Enter the resulst you want to add to the file\n");
    scanf("%s",input);

    while(!feof(file1))
        fread(&match,sizeof(match),1,file1);
    fseek(file1,sizeof(match),SEEK_END);
    fwrite(&input,sizeof(match),1,file1);
    fflush(file1);
    fclose(file1);

    file1 = fopen("matches.bin","r");
    while(!feof(file1)) {
        fread(&match,sizeof(match),1,file1);
        printf("%s %s %i %i\n",match.teamA,match.teamB,match.goalsA,match.goalsB);
    }
    fclose(file1);
}
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
user3438340
  • 49
  • 1
  • 4
  • `rw+b` is not a valid opening mode. And you need to test that the file actually opened before trying to use it. – ooga May 03 '14 at 15:49
  • `while(!feof(file1)) {...}` is wrong. Instead, you should check the return value from `fread(&match,sizeof(match),1,file1);` Also you should check if `file1 = fopen("matches.bin","r");` failed. – wildplasser May 03 '14 at 16:10
  • http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong – William Pursell May 03 '14 at 17:35

2 Answers2

1

The main problem with your approach is, that the string inputted by the user must be converted to a struct matches at some point. Doing so is an annoyingly awkward task in C: you will need to first split the user input into space-separated words or similar, to get string representations for .teamA, .teamB, .goalsA and .goalsB (e.g. using the function index from <strings.h>), and then you need to convert the string representations of the goal numbers into integer values using the atoi function from <stdlib.h>.

Once you have the new data as a struct matches, you can append the new struct to the file using commands like the following:

file1 = fopen("matches.bin", "a+b");
fwrite(&inputAsStruct, sizeof(match), 1, file1);

The file mode a+ opens the file for reading and writing, creates a new file if needed, and ensures that writes are appended at the end.

To output the records you don't need to close and re-open the file. You can just use fseek to move the file position back to the start of the file:

fseek(file1, 0, SEEK_SET);

Finally, as others pointed out, feof may not detect the end of file reliably. I believe it is only guaranteed to work after the fread failed once because it reached the end of file, so you should check the return value of fread instead.

jochen
  • 3,728
  • 2
  • 39
  • 49
0

Here is a similar method...

void addResult()
   {
   struct matches match;  /* Structure to write & read */
   char input[100];       /* User input buffer. */
   FILE *file1=NULL;      /* file handle. */

   /* Initialize 'match' from user input. */
   printf("Enter team A name:\n");
   fgets(match.teamA, sizeof(match.teamA), stdin);

   printf("Enter team A goals: \n");
   fgets(input, sizeof(input), stdin);
   match.goalsA = atoi(input);

   printf("Enter team B name:\n");
   fgets(match.teamB, sizeof(match.teamB), stdin);

   printf("Enter team B goals: \n");
   fgets(input, sizeof(input), stdin);
   match.goalsB = atoi(input);

   /* Open the file in 'append/read/binary' mode */
   file1 = fopen("matches.bin","a+b");
   if(NULL == file1)
      {
      fprintf(stderr, "fopen() failed.  errno[%d]\n", errno);
      goto CLEANUP;
      }

   /* write the new match record at the end of the file. */
   fwrite(&match, sizeof(match), 1 ,file1);

   /* Rewind the file handle to the beginning of the file. */
   fseek(file1, 0L, SEEK_CUR);

   /* List all file records. */
   while(!feof(file1)) 
      {
      fread(&match,sizeof(match),1,file1);
      printf("%s %s %i %i\n",
         match.teamA,
         match.teamB,
         match.goalsA,
         match.goalsB
         );
      }

   /* Clean-up allocated resources & return. */
   CLEANUP:

   if(file11)
      fclose(file1);
   }
Mahonri Moriancumer
  • 5,993
  • 2
  • 18
  • 28