Как уже упоминалось в комментариях, существует множество проблем: от не выделения памяти для char *temp
до использования массива char длиной 9 для хранения длинного числа из 9 символов, не оставляя места для завершающего символа.
Пытаясь внести как можно меньше изменений, я бы изменил размер ssn
в вашей структуре с 9 на 10, чтобы завершающий символ сохранялся. Имейте в виду, что вы могли бы использовать целое число для хранения этих данных, и это было бы более эффективным с точки зрения хранения памяти.
Еще одна вещь, на которую я хотел бы обратить внимание, это ваш массив struct student allStudents[1000]
. Вы немедленно выделяете 1000 * sizeof(struct)
байт, даже если в вашей базе данных есть только 2 записи. Возможно, лучшим подходом будет использование связанного списка. Или просто наличие массива указателей структуры (struct student *allStudents[1000]
), который изначально занимал бы намного меньше памяти, но вам пришлось бы выделять память для каждой новой структуры.
Я предполагаю, что вам не разрешено изменять файл students.db
, но нам все еще нужно добавить этот завершающий символ, поэтому в файле будет 69 байт для отдельной записи и 70 байт в структуре. Если вам разрешено, я предлагаю вам изменить его.
struct student {
// max allowed first and last name length should be 29 to ensure a space for terminating character
char first[30];
char last[30];
char ssn[10];
}
struct student allStudents[1000];
void findStudents() {
int counter = 0;
// if you want to just read the file use "r" mode, if you're writing in it you can use "r+" or "w+", but there is no "rt" as far as I know
FILE *fp = fopen("students.db", "r");
// you should always check if file is opened
if(fp == NULL) {
printf("File not opened");
return;
}
// allocate memory where you will store a single record read from a file
// note -1 since your struct is now 70bytes large and a record in file is 69
// and for that reason we are using calloc instead of malloc, since calloc fills allocated memory with zero
char *temp = (char*) calloc(1, sizeof(struct student) - 1);
// instead of using fgetc for reading a single character, it's better to use fread here
// fread returns number of elements successfully read which should be 69 if everything is alright
while( ( fread(temp, 1, sizeof(struct student) - 1, fp) ) == sizeof(struct student) - 1 ) {
// copy the content we read into the structure
// we copy only 69 bytes here, leaving the last byte of structure untouched
// and it will be 0x00 (terminating character for your ssn)
memcpy(&allStudents[counter], temp, sizeof(struct student) - 1);
counter++;
}
// free the allocated memory and close the file since you won't be using them anymore
free(temp);
fclose(fp);
}
Я бы также предложил вам вернуть количество прочитанных записей из вашей базы данных student.db
.
Я написал этот код в предположении, что вы не можете изменить файловую структуру student.db
, но если вам разрешено, пожалуйста, рассмотрите упомянутые предложения.