如何解决C中读/写二进制文件的分段错误

时间:2014-10-25 23:48:43

标签: c file binary structure

这是我试图写入二进制文件

的副本并从中读取的结构定义
   typedef struct carType Car;
struct carType {
   int vehicleID;
   char make[20];
   char model[20];
   int year;
   int mileage;
   double cost;
   Car *next;
};

这是我写入二进制文件的代码(Car的状态)

   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);
}

这是我从二进制文件(到汽车状态)读取的代码

    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
    while(!feof(ftp))
    {
            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);
} 

上次因未将内存分配给新车Why am I getting a segmentation failure?而出现分段错误。这次我确保这样做了。我检查了一个Segmentation fault when reading a binary file into a structureSegmentation fault while reading binary file in C,但我的字段是值,而不是指针。 有没有人看到一个明显的问题?每当我尝试运行时,我无法测试任何bc,我得到了这个错误。问题似乎是阅读,但我不确定写作中的某些代码是否导致阅读失败

1 个答案:

答案 0 :(得分:0)

'0'不是空终止符。 0或'\ 0'是(注意第一个上没有引号,第二个上没有引号)。 '0'是值48,而不是零。

这些是有效选项。

char separator = 0;

char separator = '\0';

您有错误:

fwrite(start->model, sizeof(char), strlen(start->make), ftp);   // 'make' size used to write 'model'

其次,您可以简化代码,而不是将分隔符null作为单独的步骤编写,只需写出完整的字符串,包括空终止符。

fwrite(start->make, 1, strlen(start->make) + 1, ftp);

但是,您打算如何重新读取字符串?您将使用什么函数调用来读取二进制中的字符串,该字符串可能是可变长度的,具有空终止符?最好是使用sizeof而不是strlen编写填充缓冲区。

fwrite(start->make, 1, sizeof(start->make), ftp);

但是,即使这很脆弱,因为如果将struct成员从固定字符数组更改为字符串(指针),sizeof()将静默返回不同的值。使用常量更安全。

const int SMALL_STRING_LEN = 20;
const int MAKE_LEN = SMALL_STRING_LEN;
const int MODEL_LEN = SMALL_STRING_LEN;

char make[MAKE_LEN];
char make[MODEL_LEN];

fwrite(start->model, 1, MODEL_LEN, ftp);
fwrite(start->make, 1, MAKE_LEN, ftp);