根据学校教的东西整的(本人大一,别杠,杠就是你对,我才刚接触这个)
结构体数组的方式存在存在有限制的情况。目前我还不会如何将结构体数组进行动态扩充。
每次存到记事本里的样子大概就这样。能够通过输入的语数英理综来计算总分,总分是不需要输入的。
以下是程序运行的样子。
程序在打开的时候就会直接读取好文件里的内容。
在我输入了一个玛卡以后
删除了张三
之后选择退出程序,然后新的内容保存到文件里
以下是代码。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct student
{
char name[8];
char id[20];
float score[5];
char sex[3];
struct student* next;
}STULIST;//定义一个可以存放学生信息的链表
typedef struct List
{
STULIST*head;
}List;//链表的头
void input(List*list);//输入信息
void output(List* list);//打印成绩单
void search(List* list);//根据学号查询
void change(List* list);//根据姓名查找到人以后修改
void delete_student(List* list);//根据姓名删除学生
int is_id(char mid[]);//判断id是否输入正确
int save_file(List* list);//保存链表内容到文件
int read_file(List* list);//预存文件到链表
STULIST* free_list(List* list);//释放链表
int main()
{
int select = 1;//选择
List list;//定义链表头
list.head = NULL;
read_file(&list);//预存文件进入链表
/*交互界面*/
while (select != 0)
{
printf("***************************************\n");
printf("** 成绩信息管理 **\n");
printf("**===================================**\n");
printf("** 1. 成绩录入 **\n");
printf("** 2. 数据修改 **\n");
printf("** 3. 数据查询 **\n");
printf("** 4. 数据删除 **\n");
printf("** 5. 打 印 **\n");
printf("**-----------------------------------**\n");
printf("** 0. 退 出 **\n");
printf("***************************************\n");
printf("请选择:");
scanf_s("%d", &select);
switch (select)
{
case 1:
input(&list);
break;
case 2:
change(&list);
break;
case 3:
search(&list);
break;
case 4:
delete_student(&list);
break;
case 5:
output(&list);
break;
case 0:
break;
default:
break;
}
}
/*判断是否保存入文件*/
if (save_file(&list) == 0)
{
printf("保存失败\n");
}
else
{
printf("保存成功\n");
}
free_list(&list);
return 0;
}
/*输入*/
void input(List* list)
{
/*定义一个暂存输入的结构体*/
STULIST* p = (STULIST*)malloc(sizeof(STULIST));
/*定义一个链表从链表头开始*/
STULIST* q=NULL;
int j;
char leason[4][8] = { "语文","数学","英语","理综" };//保存课目名字,便于扩增。
char mname[8] = { 0 };//暂存的名字
char mid[20] = { 0 };//暂存的id。
float mscore[5];//存放各科的成绩
char msex[3] = { 0 };//性别
if (p == NULL) return;//申请内存失败则退出程序
p->next = NULL;//使链表末尾为空
printf("请输入名字:");
scanf_s("%s", mname, 8);
while (1)
{
printf("请输入id:");
scanf_s("%s", mid, 20);
if (is_id(mid) != 0)
{
printf("你输入的id有问题,请重新输入");
}
else
{
break;
}
}
printf("请输入性别:");
scanf_s("%s", msex, 3);
for (j = 0; j < 4; j++)
{
printf("请输入%s的成绩:", leason[j]);
scanf_s("%f", &mscore[j]);
}
/*将暂存的存到链表里*/
strcpy_s(p->name, mname);
strcpy_s(p->id, mid);
strcpy_s(p->sex, msex);
/*将各科分数存到链表里*/
for (j = 0; j < 4; j++)
{
p->score[j] = mscore[j];
}
q = list->head;
if (q == NULL)//判断如果链表头为空则存到链表头
{
list->head = p;
}
else
{
q = list->head;
/*找到链表的末尾*/
while (q->next)
{
q = q->next;
}
q->next = p;
}
}
/*输出*/
void output(List *list)
{
int j;
STULIST* q;
q = (STULIST*)malloc(sizeof(STULIST));
q = list->head;
printf("姓名\t性别 学号\t语文\t数学\t英语\t理综\t总分\t\n");
while(q)
{
printf("%s\t", q->name);
printf("%-5s", q->sex);
printf("%-10s\t", q->id);
q->score[4] = 0;
for (j = 0; j < 5; j++)
{
printf("%.1f\t", q->score[j]);
q->score[4] += q->score[j];
}
printf("\n");
q = q->next;
}
}
/*查找*/
void search(List *list)
{
STULIST* q = list->head;
char m_id[20] = { 0 };//定义一个用于比较寻找的id
int j;
int myes = 1;//判断当找不到该学生时是否输入
printf("请输入你要查找的学号:");
scanf_s("%s", m_id,20);
while(q)
{
if (strcmp(q->id, m_id) == 0)
{
break;
}
q = q->next;
}
if (q == NULL)
{
printf("没找到该学生");
printf("你要输入吗?1--输入,2--放弃\n");
scanf_s("%d", &myes);
if (myes != 1)
{
printf("你放弃了输入\n");
return;
}
else
{
input(list);
return;
}
}
printf("该学生的成绩为:\n");
printf("姓名\t性别 学号\t语文\t数学\t英语\t理综\t总分\t\n");
printf("%s\t", q->name);
printf("%-5s", q->sex);
printf("%-10s\t", q->id);
q->score[4] = 0;
/*计算总分并且存入*/
for (j = 0; j < 5; j++)
{
printf("%.1f\t", q->score[j]);
q->score[4] += q->score[j];
}
printf("\n");
}
/*修改*/
void change(List *list)
{
STULIST* q = list->head;
int j;
int flag = 0;//定义flag反应是否找到该学生
char m_name[8] = { 0 };
int change_score = 0;
int myes = 1;//用于判断如果找不到该学生是否输入。
printf("请输入你要修改的学生名字:");
scanf_s("%s", m_name, 8);
while(q)
{
if (strcmp(q->name, m_name) == 0)
{
flag = 1;
break;
}
q = q->next;
}
if (flag)
{
printf("该学生当前的成绩为:\n");
printf("姓名\t性别 学号\t语文\t数学\t英语\t理综\t总分\t\n");
printf("%s\t", q->name);
printf("%-5s", q->sex);
printf("%-10s\t", q->id);
q->score[4] = 0;
for (j = 0; j < 5; j++)
{
printf("%.1f\t", q->score[j]);
q->score[4] += q->score[j];
}
printf("\n");
printf("请输入你要修改的成绩:\n");
printf("1-语文,2-数学,3-英语,4-理综\n");
scanf_s("%d", &change_score);
while (change_score)
{
switch (change_score)
{
case 1:
printf("请输入你要修改的语文成绩:");
scanf_s("%f", &q->score[0]);
printf("是否要继续修改,如果是请输入修改科目的序号,否则输入零\n");
printf("1-语文,2-数学,3-英语,4-理综\n");
scanf_s("%d", &change_score);
break;
case 2:
printf("请输入你要修改的数学成绩:");
scanf_s("%f", &q->score[1]);
printf("是否要继续修改,如果是请输入修改科目的序号,否则输入零\n");
printf("1-语文,2-数学,3-英语,4-理综\n");
scanf_s("%d", &change_score);
break;
case 3:
printf("请输入你要修改的英语成绩:");
scanf_s("%f", &q->score[2]);
printf("是否要继续修改,如果是请输入修改科目的序号,否则输入零\n");
printf("1-语文,2-数学,3-英语,4-理综\n");
scanf_s("%d", &change_score);
break;
case 4:
printf("请输入你要修改的理综成绩:");
scanf_s("%f", &q->score[3]);
printf("是否要继续修改,如果是请输入修改科目的序号,否则输入零\n");
printf("1-语文,2-数学,3-英语,4-理综\n");
scanf_s("%d", &change_score);
break;
default:
printf("你输入的选择有问题,请重新输入:");
break;
}
}
printf("该学生修改后的成绩为:\n");
printf("姓名\t性别 学号\t语文\t数学\t英语\t理综\t总分\t\n");
printf("%s\t", q->name);
printf("%-5s", q->sex);
printf("%-10s\t", q->id);
q->score[4] = 0;
for (j = 0; j < 5; j++)
{
printf("%.1f\t", q->score[j]);
q->score[4] += q->score[j];
}
printf("\n");
}
else
{
printf("目前没有该学生。\n");
printf("你要输入吗?1--输入,2--放弃\n");
scanf_s("%d", &myes);
if (myes != 1)
{
printf("你放弃了输入\n");
return;
}
else
{
input(list);
return;
}
}
}
/*保存到文件*/
int save_file(List* list)
{
int j;
STULIST* q;
q = list->head;
FILE* fp;
fopen_s(&fp,"D:\\manage.txt", "wt");
if (fp == NULL)
{
printf("文件打开失败\n");
return 0;
}
if (!q) return 0;
fprintf_s(fp, "姓名\t性别\t学号\t\t语文\t数学\t英语\t理综\t总分\t\n");
while (q)
{
fprintf_s(fp,"%s\t", q->name);
fprintf_s(fp,"%-5s\t", q->sex);
fprintf_s(fp,"%-10s\t", q->id);
q->score[4] = 0;
for (j = 0; j < 5; j++)
{
fprintf(fp,"%.1f\t", q->score[j]);
q->score[4] += q->score[j];
}
fprintf(fp,"\n");
q = q->next;
}
printf("文件保存成功!");
return 1;
}
/*预存(目前有问题)*/
int read_file(List* list)
{
int j;
STULIST* q=NULL;
STULIST* p;
FILE* fp;
char* word=NULL;
fopen_s(&fp, "D:\\manage.txt", "r");
if (fp == NULL)
{
printf("文件打开失败");
return 0;
}
fseek(fp, strlen("姓名\t性别\t学号\t\t语文\t数学\t英语\t理综\t总分\t\n"), 0);
while (getc(fp)!=EOF)
{
fseek(fp, -1, 1);
p = (STULIST*)malloc(sizeof(STULIST));
if (p == NULL) return 0;
fscanf_s(fp, "%s\t", p->name,8);
fscanf_s(fp, "%s\t", p->sex,3);
fscanf_s(fp, "%s\t", p->id,20);
for (j = 0; j < 5; j++)
{
fscanf_s(fp, "%f\t", &p->score[j]);
}
p->next = NULL;
if (list->head == NULL)
{
list->head = q = p;
}
else
{
if (q == NULL) return 0;
q->next = p;
q = p;
}
}
fclose(fp);
return 1;
}
/*删除*/
void delete_student(List* list)
{
int i;
int myes;
STULIST* q =NULL;
STULIST* p = list->head;
char mname[8] = {0};
printf("请输入你要删除的学生名字:");
scanf_s("%s", mname,8);
for (q = NULL, p = list->head; p; q = p, p = p->next)
{
if (strcmp(p->name, mname) == 0)
{
break;
}
}
if (p==NULL)
{
printf("没有该学生\n");
}
else
{
printf("该学生的成绩为:\n");
printf("姓名\t性别 学号\t语文\t数学\t英语\t理综\t总分\t\n");
printf("%s\t", p->name);
printf("%-5s", p->sex);
printf("%-10s\t", p->id);
p->score[4] = 0;
for (i = 0; i < 5; i++)
{
printf("%.1f\t", p->score[i]);
p->score[4] += p->score[i];
}
printf("\n");
printf("是否删除该学生?1--是,2--否\n");
scanf_s("%d", &myes);
if (myes == 1)
{
if (q)
{
q->next = p->next;
}
else
{
list->head = p->next;
}
free(p);
printf("删除完毕\n");
}
else
{
printf("已保留\n");
}
}
}
/*判断id输入是否正确*/
int is_id(char mid[])
{
unsigned int i;
for (i = 0; i < strlen(mid); i++)
{
if (mid[i] < '0' || mid[i] > '9') return 1;
}
return 0;
}
STULIST* free_list(List* list)
{
STULIST* p;
while (list->head != NULL)
{
p = list->head;
list->head = list->head->next;
free(p);
}
printf("链表释放完毕!按任意键返回.\n");
return list->head;
}
昨晚新学了如何将链表进行排序,于是加了这个按照总分排名的功能。
新加了将整个成绩单按照总分来排名。以下是运行截图。输入一个刘二狗的成绩,发现他的成绩排名不应该在最后。
输入6排序以后,得到刘二狗排到倒数第二,整个排名按照总分从大到小。
以下是代码。
/*按照总分排名*/
void grades_sort(List* list)
{
STULIST* h1, * p1, * p2, * q;
if (list->head == NULL)
{
printf_s("目前尚未录入学生成绩!\n");
return;
}
h1 = list->head;
list->head = h1->next;
h1->next = NULL;
while (list->head != NULL)
{
q = list->head;
list->head = q->next;
p1 = p2 = h1;
while (p2 != NULL)
{
if (q->score[4] > p2->score[4]) break;
p1 = p2;
p2 = p2->next;
}
if (p1 == p2)
{
q->next = p2;
h1 = q;
}
else
{
p1->next = q;
q->next = p2;
}
}
printf_s("排序完毕!\n");
list->head = h1;
}