qfedu-c-level/day14/homework/h3.c

99 lines
2.4 KiB
C
Raw Permalink Normal View History

// 按行读取score.txt文件的所有内容并生成有序的链表且打印链表数据。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct stu_s
{
int sid;
char dh; // 逗号
float score;
struct stu_s *next;
} STU;
// 打印链表
void show(STU *head)
{
if (NULL == head)
{
printf("数据为空,无法打印\n");
return;
}
STU *tp = head;
printf("\n学号\t成绩\n");
while (NULL != tp)
{
printf("%d\t%.2f\n", tp->sid, tp->score);
tp = tp->next;
}
}
// 添加学生
STU *insert_stu(STU *head, STU *item)
{
// 如果头指针为空,说明链表为空,直接将新建的节点作为头指针
if (head == NULL)
{
head = item;
}
else
{
// 如果头指针不为空,说明链表不为空,需要找到链表的尾部,将新建的节点插入到尾部
STU *p = head; // 创建一个临时指针,用来保存头指针,防止头指针丢失
while (p->next != NULL) // 当 p 的下一个节点不为空时,说明 p 不是尾部
{
p = p->next; // p 一直向后移动,直到找到尾部
}
p->next = item; // 将 item 插入到尾部
}
return head; // 返回头指针
}
int main()
{
FILE *fp = fopen("score.txt", "r");
if (NULL == fp)
{
return 1;
}
STU *head = NULL; // 建立链表头节点
// 计算文件大小
fseek(fp, 0, SEEK_END);
long file_size = ftell(fp);
printf("score.txt 文件大小: %ld B\n", file_size);
// 重置光标位置
fseek(fp, 0, SEEK_SET); // 等同于使用 rewind(fp);
// 按照 STU 的结构存储数据,计算出以存放学生数量
int stu_num = file_size / sizeof(STU);
printf("学生数量: %d\n", stu_num);
// printf("\n学号\t成绩\n");
for (int i = 0; i < stu_num; i++)
{
// 为新的链表节点分配内存空间
STU *s = calloc(1, sizeof(STU));
// 从文件中读取一个学生的数据
fread(s, sizeof(STU), 1, fp);
head = insert_stu(head, s); // 插入链表节点
}
show(head); // 显示链表内容
// 最后循环释放动态申请的内存
STU *free_tp = head;
while (free_tp != NULL)
{
STU *to_free_this_p = free_tp;
free_tp = free_tp->next;
free(to_free_this_p);
}
fclose(fp);
return 0;
}