使用fscanf将数据输入到动态结构指针数组中?

时间:2013-02-22 20:18:33

标签: c segmentation-fault dynamic-arrays scanf

我有一项任务,并且遇到了一些障碍。以下代码应该从文件中获取输入,将其读入我已定义的结构中,并且不对输入行的数量进行任何限制。但是,它在行 24

的段错误
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 typedef struct __student {
6         int ID;
7         char fname[33];
8         char lname[33];
9         float grade;
10 } student;
11
12 void partA(FILE *fp) {
13
14         int i, r;
15         i = r = 0;
16         int N = 1000;
17         student **S;
18
19         S = (student **)malloc(sizeof(student *) * N);
20
21
22         while(!feof(fp)){
23                 fscanf(fp, "%d %[^,], %s %f", &S[i]->ID, S[i]->lname, S[i]->fname, &S[i]->grade ); // segfault occurs on this line
24                 printf("%d %s %s %f\n", S[i]->ID, S[i]->fname, S[i]->lname, S[i]->grade);
25                 i++;
26                 printf("Something's happening, at least");
27                 if(i == N){
28                         N *= 2;
29                         S = (student **)realloc(S, sizeof(student) * N);
30                         if(S == NULL) {
31                                 printf("Memory reallocation failed; Fatal error.");
32                                 break;
33                         }
34                 }
35         }
36 }

之前我测试过代码,虽然那时我使用的是静态数组,并希望更改为动态大小。然而,除了行号之外,即使gdb提供的帮助也很少。我是否需要单独malloc每个学生结构,或者我错过了一些完全不同的东西?

编辑:当我在while循环中为每个学生分配内存时,代码似乎有效:

S[i] = (student *)malloc(sizeof(student));

所以这似乎解决了这个问题。我会做一些测试以确保。

2 个答案:

答案 0 :(得分:1)

除了你的malloc问题,你还有两行的主要问题

while(!feof(fp)){
    fscanf(fp, "%d %[^,], %s %f", &S[i]->ID, S[i]->lname, S[i]->fname, &S[i]->grade ); // segfault occurs on this line

一个问题是,您的lnamefname字段是固定大小为33的字符数组,这意味着如果您的输入在此时的字符数超过32个字符,那么您将运行结束数组和腐败的东西。另一个问题是你没有检查fscanf的返回值以查看是否出现了问题(例如EOF),导致你在到达文件末尾时尝试打印垃圾记录。你想要的是:

while (fscanf(fp, "%d %32[^,],%32s%f", &S[i]->ID, S[i]->lname, S[i]->fname, &S[i]->grade) == 4) {

用于循环控制。

修改

while(!feof(fp))的问题(及其几乎总是错误的原因)是feof(fp)仅在您尝试读取PAST文件末尾后才返回true。在读完最后一行后,feof(fp)仍然返回false,因此您再次进入循环并尝试读取另一行。该读取失败,但由于您没有检查fscanf的返回值,因此您没有意识到它,而是在您的数组中获得了额外的垃圾值。

答案 1 :(得分:0)

在第19行,你为N学生指针分配了足够的空间,但没有为他们自己的学生结构分配空间。您需要执行以下操作:

for( int i = 0; i < N; i++) {
     S[i] = malloc(sizeof(struct __student));
}