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

99 lines
2.4 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 按行读取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;
}