Why isn't fread reading in the correct integer

2019-06-14 18:30发布

This question was just to clarify why the correct output(year) isn't being printed correctly, given the following code.

For future readers, the issue was that the fget() function read off a byte that was supposed to be a byte that belonged to year, causing the year to not be printed correctly.

Here is my code Car structure

      typedef struct carType Car;
struct carType {
   int vehicleID;
   char make[20];
   char model[20];
   int year;
   int mileage;
   double cost;
   Car *next;
};

Code to write to binary file

  void writeBinFile(Car *headPointer)
{
     char fileName[20];
     //prompt user for name of textfile to print to 
    scanf("%s", fileName);
    FILE *ftp;
    Car *start =  headPointer->next;
    ftp = fopen(fileName, "wb");
    char separator = '0';
    while(start != NULL)
    {
       //write out 1 cell of data, cell contains 4 bytes
        fwrite(&start->year,sizeof(int), 1, ftp);
        fwrite(start->make,sizeof(char), strlen(start->make), ftp);
        fwrite(&separator, sizeof(char), 1, ftp); 
        fwrite(start->model, sizeof(char), strlen(start->make), ftp);
        fwrite(&separator, sizeof(char), 1, ftp);
        fwrite(&start->cost, sizeof(float), 1, ftp);
        fwrite(&start->mileage, sizeof(float),1,ftp);
        fwrite(&start->vehicleID, sizeof(int), 1, ftp);
        start = start->next;
    }
    fclose(ftp);
}

And code to read in a binary file

   void readFromBinFile(Car *headPointer)
{
      char fileName[20];
     //prompt user for name of textfile to print to 
    scanf("%s", fileName);
    FILE *ftp;
    Car *previous =  headPointer;
    ftp = fopen(fileName, "rb");
    Car *current;

    //go until the end of file is reached
    int c;
    while((c = fget(ftp)) != EOF)
    {
            current = (Car *)malloc(sizeof(Car));
            previous->next = current;
             //program receives 1 cell, that cell contains 4 bytes
             fread(&current->year, sizeof(int),1,ftp);
             printf("%d\n",current->year);
             char make[25];
             int count = 0;
             char oneAtATime= 'a';
             while(oneAtATime != '0') 
             { 
                    fread(&oneAtATime, sizeof(char),1,ftp);
                   if(oneAtATime!='0')
                   {
                      make[count] = oneAtATime;
                        count++;
                   }
            } 
            make[count] = 0;
           strcpy(current->make, make);
             char model[25];
              count = 0;
              oneAtATime= 'a';
             while(oneAtATime != '0') 
             { 
                    fread(&oneAtATime, sizeof(char),1,ftp);
                   if(oneAtATime!='0')
                   {
                      model[count] = oneAtATime;
                        count++;
                   }
            } 
            model[count] = 0;
           strcpy(current->model, model);
           fread(&current->cost, sizeof(float),1, ftp);
           fread(&current->mileage, sizeof(int),1,ftp);
           fread(&current->vehicleID, sizeof(int),1,ftp);
         previous = previous->next;
    } 
    fclose(ftp);
} 

Here is my data that I am trying to write/read from bin file.(loaded this from the read/write to text which works)

2014 Toyota Rav4 cost:$40000 mileage:3000, vehicleID:1
2014 Toyota Celica cost:$3220 mileage:2222, vehicleID:3

In the read binary method, I use this line of code for debugging purposes

   printf("%d\n",current->year);

Which should print 2014 in both instances. However when i try running the code, this is what gets printed

1275068423
1811939335

Is there something i am missing in my read and my write method that is causing the year to be so off?

标签: c file struct
1条回答
干净又极端
2楼-- · 2019-06-14 19:10

You have a logic error. The line

while((c = fgetc(ftp)) != EOF) // Assuming you meant to use fgetc not fget

reads the first character from ftp that is supposed to be part of the current->year. When you execute

         fread(&current->year, sizeof(int),1,ftp);

you are reading the wrong data. If sizeof(int) is 4 in your platform, you are picking up 3 bytes of data from the saved year and one byte from the saved make.

My suggestion to fix it:

int year;
while(1)
{
        if ( fread(&year, sizeof(int),1,ftp) != 1 )
        {
           // No more data to read.
           break;
        }

        current = (Car *)malloc(sizeof(Car));
        previous->next = current;

        current->year = year;

        // Proceed with reading the rest of the data.
        // Make sure you check the return value of every call
        // to `fread` before proceeding to the next line of code.
查看更多
登录 后发表回答