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

标签 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 每个 student 结构,还是我在这里遗漏了一些完全不同的东西?

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

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

这似乎解决了问题。我将运行一些测试来确定。

最佳答案

除了你的 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 文件末尾。阅读最后一行后,feof(fp) 仍然返回 false,因此您再次进入循环并尝试阅读另一行。读取失败,但由于您没有检查 fscanf 的返回值,您没有意识到这一点,而是在您的数组中获得了一个垃圾额外值。

关于c - 使用 fscanf 将数据输入动态结构指针数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15032522/

相关文章:

c - 为从属端口名称指定别名或重命名

c++ - ghdl 缺少 util.misc_conv_pkg ubuntu 14.04

c++ - minko - 无法编译 dev 分支

c++ - 卷到物理驱动器

python - 如何终止在后端执行长时间运行的 C/C++ 代码的 python 解释器?

c - 二叉搜索树中的段错误(核心转储)

c - 为什么这段代码在我的笔记本电脑 (OSX 10.9) 上运行良好,但在服务器 (Linux) 上却出现段错误?

Java Finalizers,哪些任务是真正必要的

c - 尝试从 .txt 文件复制整数时出现段错误

c - 在 C 中给定开始和结束内存地址的意外行为遍历数组