为什么我会出现分段失败?

这是我的代码。 我正在做一些C练习来处理文件

我不认为结构定义是问题,但我也发布它以给出一些上下文。

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

我认为这个function会导致分段失败。

  void TextLoad(Car *headPointer) { char fileName[20]; //prompt user for name of textfile to print to scanf("%s", fileName); FILE *fpt; //estabish an IO connection fpt = fopen(fileName, "r"); //current car to be printed Car *current; current = headPointer->next; while(fscanf(fpt,"%d %s %s cost:$%f mileage:%d, vehicleID:%d",&current->year, current->make, current->model,&current->cost,&current->mileage, &current->vehicleID) != EOF) { current = current->next; } fclose(fpt); } 

我测试过这个函数的文件有这个内容

  2014 Toyota Celica cost:$90000 mileage:5000, vehicleID:1 2014 Toyota Rav4 cost:$4500 mileage:4000, vehicleID:2 

我所拥有的基本上是一个struct car,我想使用文件中的信息来初始化struct car的字段。 有谁知道这种细分失败的来源? 我检查了其他线程fclose()导致分段错误 , 代码失败,分段错误,但我确保调用fclose关闭IO连接,我没有初始化另一个文件指针,但工作正常。 我认为问题是fscanf,但我的格式不正确吗?

它看起来像你没有为汽车结构分配空间。 您创建一个指针,但是您必须使用malloc为它创建内存。 我认为您可以使用sizeof(carType)作为malloc的参数来获取结构的大小。 已经有一段时间了,因为我使用直接c这样,在C ++和C#中你可以使用new来调用构造函数并且编译器执行内存管理。

所以它看起来像这样:

 Car *current = malloc(sizeof(carType));//you might want to try sizeof(car) if that doesn't work 

您似乎已经调整了一个循环来编写结构并使用它来读取结构。

问题是您正在阅读的区域可能未被分配。 所以你的数据被读入了黑色和段错误。

要按原样工作,您的函数应该会收到一个有效的headPointer 。 你可以通过接收指向 headPointer本身的指针做得更好, headPointer的值可能是NULL(即如果你刚刚开始)。 如果是这种情况,则更新headPointer值,使其成为有效的结构。

在循环期间重复相同的操作。

实际上,与创建新结构相关的操作应该外包给一个单独的function。

然后循环应该:

 *curPointerPtr = headPointerPointer; while (!feof(fpt)) { // We need to allocate a new Car. *curPointer = newCar(); // Check it is not NULL (unless newCar throws an error) fscanf(into *curPointer) // prepare curPointer to accept next *curPointer = (*curPointer)->next; } 

分配新车的function也可以最小化它(至少null所有指针和零终止所有字符串):

 Car *newCar(void) { Car *car; car = malloc(sizeof Car); if (NULL == car) { // Throw an error } else { // ALSO initialize the structure - good practice car->make[0] = 0x0; car->model[0] = 0x0; car->next = NULL; } return car; }