Считывание структуры с файла - C (СИ)
Формулировка задачи:
написала программу формирования структуры студент (факультет, кафедра, ФИО, специальность: код и расшифровка, курс, группа) и поиска информации по ФИО в формате: имя, специальность:код и расшифровка, курс, группа (вывод и на экран, и в файл). С использованием односвязного списка.
Нужно переделать программу на считывание структуры из файла. Файл вида:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
typedef struct stud
{
char faculty[5];
char department[5];
int idx;
char name[100];
struct {
int code;
char text[100];
} specialization;
int course;
char group[10];
struct stud *next;
} stud;
int main() {
stud* head = NULL;
stud* tail = NULL;
char nameBuf[100], s[100];
int idx = 1;
FILE *finp, *fres;
if ((finp = fopen ("lab5-input.txt", "w")) == 0)
{
puts ("Error with input file!");
return 0;
}
if ((fres = fopen ("lab5-result.txt", "w")) == 0)
{
puts ("Error with result file!");
return 0;
}
do {
printf ("%i --- \n", idx);
// enter name
printf ("Enter student name (empty string to quit): ");
gets (nameBuf);
if (strlen (nameBuf) > 0)
{
// add new record
if (head == NULL) {
tail = head = (stud*) malloc (sizeof (stud));
} else {
tail = tail->next = (stud*) malloc (sizeof (stud));
}
// enter other data
strcpy (tail->name, nameBuf);
printf ("Enter faculty: ");
scanf ("%s",tail->faculty);
printf ("Enter department:");
scanf ("%s",tail->department);
printf ("Enter specialization (code and description): ");
scanf ("%i %s", &(tail->specialization.code), tail->specialization.text);
printf ("Enter course: ");
scanf ("%i", &(tail->course));
printf ("Enter group: ");
scanf ("%s", tail->group);
gets (s);
tail->idx = idx++;
tail->next = NULL;
}
} while (strlen (nameBuf) > 0);
stud* cur = head;
fprintf (finp, "---------------------------------STUDENTS-------------------------------|\n");
fprintf (finp, "|FACULTY|DEPARTMENT| NAME | SPECIAL |COURSE|GROUP|\n");
fprintf (finp, "| | | | CODE | TEXT | | |\n");
fprintf (finp, "------------------------------------------------------------------------|\n");
while (cur != NULL)
{
fprintf (finp, "|%7s|%10s|%20s|%7d|%10s|%6d|%5s|\n", cur->faculty, cur->department,cur->name, cur->specialization.code, cur->specialization.text, cur->course, cur->group);
stud* pocket = cur->next;
cur = pocket;
}
fprintf (finp, "-------------------------------------------------------------------------------- \n");
int perms;
do
{
// enter name
printf ("\nEnter necessary student's name (empty string to quit): ");
gets (nameBuf);
if (strlen (nameBuf) > 0)
{
stud* cur = head;
while ((cur != NULL) && (strcmp(cur->name, nameBuf)!=0))
{
stud* pocket = cur->next;
cur = pocket;
}
if (cur == NULL) printf ("No such student! \n");
else if (strcmp (cur->name, nameBuf) == 0)
{
printf ("--------------------STUDENTS-------------------------|\n");
printf ("| NAME | SPECIAL |COURSE|GROUP|\n");
printf ("| | CODE | TEXT | | |\n");
printf ("----------------------------------------------------- \n");
fprintf (fres, "--------------------STUDENTS-------------------------|\n");
fprintf (fres, "| NAME | SPECIAL |COURSE|GROUP|\n");
fprintf (fres, "| | CODE | TEXT | | |\n");
fprintf (fres, "----------------------------------------------------- \n");
printf ("|%20s|%7d|%10s|%6d|%5s|\n", cur->name, cur->specialization.code, cur->specialization.text, cur->course, cur->group);
printf ("----------------------------------------------------- \n");
fprintf (fres, "|%20s|%7d|%10s|%6d|%5s|\n", cur->name, cur->specialization.code, cur->specialization.text, cur->course, cur->group);
fprintf (fres, "----------------------------------------------------- \n");
stud* pocket = cur->next;
free(cur);
cur = pocket;
}
}
} while (strlen (nameBuf) > 0);
fclose(finp);
return 0;
}Решение задачи: «Считывание структуры с файла»
textual
Листинг программы
#include <stdio.h>
#include <stdlib.h>
#define FILE_NAME "lab5.txt"
typedef struct stud
{
char faculty[5];
char department[5];
int idx; /* это поле для чего? */
char name[100];
struct {
int code;
char text[100];
} specialization;
int course;
char group[10];
struct stud *next;
} stud_t; /* так как-то привычнее */
int main(void) {
stud_t * head = NULL, * tail = NULL, * current, tmp;
FILE * f;
if ( ! ( f = fopen(FILE_NAME, "r") ) ) {
perror("fopen");
exit(1);
}
while ( fscanf(f, "%4s %4s %99s %d %99s %d %9s", tmp.faculty, tmp.department, tmp.name, &tmp.specialization.code, tmp.specialization.text, &tmp.course, tmp.group) == 7 ) {
if ( ! ( current = malloc(sizeof(stud_t)) ) ) {
perror("malloc");
exit(1);
}
*current = tmp;
current->next = NULL;
if ( ! head )
head = current;
else
tail->next = current;
tail = current;
}
if ( ferror(f) || fclose(f) ) {
perror("ferror or fclose");
exit(1);
}
printf("faculty department name code text course group\n");
for ( current = head; current; current = current->next )
printf("%s %s %s %d %s %d %s\n", current->faculty, current->department, current->name, (current->specialization).code, (current->specialization).text, current->course, current->group);
while ( head ) {
tail = head->next;
free(head);
head = tail;
}
return 0;
}
Объяснение кода листинга программы
- Включаются необходимые заголовочные файлы
- Определяется название файла для чтения данных
- Создается структура
stud, которая содержит информацию о студенте, в том числе поля: факультет, отделение, индекс (возможно, уникальный идентификатор), имя, специализация (код и текст), курс и группа - Устанавливаются начальные значения переменных
headиtail, которые будут использоваться для работы с linked list (связным списком) - Открывается файл для чтения с помощью функции fopen. Если файл не может быть открыт, выводится сообщение об ошибке и программа завершается
- В цикле while считываются данные из файла в структуру
stud_tс использованием функции fscanf. Если данные успешно считаны, создается новый элемент linked list с использованием malloc, и добавляется в конец списка с помощью функций head, tail, current и next - После чтения всех данных из файла, выводится содержимое linked list с помощью цикла for и функции printf
- В цикле while освобождается память, выделенная под каждый элемент linked list, начиная с головы списка и двигаясь к хвосту
- Программа завершается, если все данные успешно обработаны и выведены.