Reputation: 13
I have to linear search with student list file.
This file is sorted by year. I have to receive the year, student name, from the file. If the name is the same, I have to add frequency to freq[]
. If it is a different name, you can add a student name structure at the end of the array. When I run gdb in Ubuntu, I can compile it, but I keep getting errors when I add frequency.
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.
Please help me
Upvotes: 1
Views: 118
Reputation: 144520
There are multiple problems in your function:
you do not test the return value of fscanf()
. Conversion failure will go undetected and you may even have an infinite loop when skipping initial records.
you should check for realloc
failure to reallocate the array.
reading buff.name
with " %s"
is risky: you should specify the maximum number of characters to store into the destination array with " %19s"
but be aware that this conversion does not allow for multiple names.
the last conversion " %*c"
is bizarre: do you intend to skip the newline this way? It will not work because the space will have consumed it already and you will instead consume the first character of the next line. You should not use fscanf()
, but use fgets()
to read a full line and sscanf()
to parse it.
it is unclear what is the purpose of the count
variable.
does freq
mean frequentation or frequency?
Here is a simplified version:
#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 capacity\n", 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;
}
Upvotes: 2