我必须用学生列表文件进行线性搜索。
此文件按年份排序。我必须从档案中收到年份、学生姓名。如果名称相同,我必须将频率添加到freq[]
。如果是其他名称,则可以在数组末尾添加学生名称结构。当我在Ubuntu中运行gdb时,我可以编译它,但当我添加频率时,我总是会出错。
In particular, this part produces a segmentation fault. If I annotated this line, there is no segmentation fault, but the execution does not stop.
Structure is here.
请帮我
您的函数中存在多个问题:
-
您不测试
fscanf()
的返回值。转换失败将无法被检测到,当跳过初始记录时,您甚至可能会有一个无限循环。 -
您应该检查
realloc
是否失败以重新分配阵列。 -
用
" %s"
读取buff.name
是有风险的:您应该指定用" %19s"
存储到目标数组中的最大字符数,但要注意,这种转换不允许使用多个名称。 -
最后一个转换
" %*c"
很奇怪:你打算这样跳过换行符吗?它不会起作用,因为空间已经消耗掉了它,而您将消耗下一行的第一个字符。您不应该使用fscanf()
,而是使用fgets()
来读取整行,使用sscanf()
来解析它 -
不清楚CCD_ 11变量的目的是什么。
-
CCD_ 12是指频率还是频度?
这里有一个简化版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_YEAR_DURATION 10
typedef struct {
char name[20];
char sex;
int freq[MAX_YEAR_DURATION];
} tName;
typedef struct {
int len;
int capacity;
tName *data;
} tNames;
int load_names_lsearch(FILE *fp, int start_year, tNames *names) {
char buf[200];
tName buff;
int num = 0; /* number of records added */
int year, i, count, year_duration;
while (fgets(buf, sizeof buf, fp)) {
if (fscanf(fp, "%d %19s %c %d", &year, buff.name, &buff.sex, &count) != 4) {
fprintf(stderr, "invalid record: %s", buf);
continue;
}
if (year < start_year || year >= start_year + MAX_YEAR_DURATION) {
/* ignore record */
continue;
}
year_duration = year - start_year;
/* try and locate same student and update freq */
for (i = 0; i < names->len; i++) {
if (strcmp(names->data[i].name, buff.name) == 0 && names->data[i].sex == buff.sex) {
names->data[i].freq[year_duration] += 1;
break;
}
}
if (i == names->len) {
/* student was not found: add new record */
/* check for available space */
if (names->len >= names->capacity) {
int new_capacity = names->len + 1000;
tName *new_data = realloc(names->data, new_capacity * sizeof(*names->data));
if (new_data == NULL) {
fprintf(stderr, "cannot reallocate data for %d capacityn", new_capacity);
return -1;
}
names->capacity = new_capacity;
names->data = new_data;
}
/* append new record */
memset(buff.freq, 0, sizeof buff.freq);
buff.freq[year_duration] = 1;
names->data[names->len++] = buff;
num++;
}
}
return num;
}