核心知识
单向链表基本操作+对文件的基本操作
使用说明
请先建好一个.txt文件并记下路径名,文件可以为空,也可以预先存好数据建议创建一个空文件,通过程序来向文件中存数据。手动去文件中存数据需要严格按照格式。
如果想预先手动存一些数据,需要按照以下格式:
在某些编译器上,姓名可能不支持中文
姓名1 语文 数学 英语 计算机 C语言 平均分 总分1
…
姓名n 语文 数学 英语 计算机 C语言 平均分 总分n
文件结尾,也就是最后一行的总分n后面不要有任何字符。
代码附上
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#define MAXNAME 30
#define MAXSUBJECT 5
#define SPACE ' '
typedef struct student
{
char name
[MAXNAME
];
int score
[MAXSUBJECT
];
double aver
;
int sum
;
} STUDENT
;
typedef struct node
{
STUDENT data
;
struct node
*next
;
} NODE
, *LIST
;
int i
, choice
;
char ch
, c
, c2
;
char s1
[10] = "name";
char s2
[10] = "average";
char s3
[10] = "sum";
char s4
[10] = "chinese";
char s5
[10] = "math";
char s6
[10] = "english";
char s7
[10] = "computer";
char s8
[10] = "c";
char FileName
[100];
LIST headp
= NULL;
void AddFscanf(NODE
);
void Instructions();
void Ask();
void SplitLine();
void AddUserInput();
void Delete();
void Inquire();
void Update();
void Sort();
void Save();
void Print();
void Free();
int main(void)
{
FILE
*fp
= NULL;
NODE head
;
NODE temp
;
headp
= &head
;
head
.next
= NULL;
temp
.next
= NULL;
printf("请输入文件的绝对路径+文件名(仅限 .txt 文件)\n\n");
printf("例如,若您要打开D盘根目录下的 info.txt 文件\n");
printf("则应输入\"D:/info.txt\"(您输入的字符均应为英文字符)\n");
scanf("%s", FileName
);
getchar();
if ((fp
= fopen(FileName
, "r")) == NULL)
{
printf("\n\"%s\" 打开失败\n\n", FileName
);
exit(EXIT_FAILURE
);
}
printf("\n\"%s\" 打开成功!\n", FileName
);
printf("\n正在鉴定文件是否为空...\n");
c2
= getc(fp
);
fclose(fp
);
if (c2
== EOF)
printf("打开的文件为空文件,仅可进行写入操作!\n");
else
{
printf("文件非空,可进行任意操作\n\n");
printf("正在重新打开该文件...\n");
if ((fp
= fopen(FileName
, "r")) == NULL)
{
printf("can't open \"%s\" \n", FileName
);
exit(EXIT_FAILURE
);
}
printf("正在读取该文件中的数据...\n");
while (1)
{
fscanf(fp
, "%s", temp
.data
.name
);
for (i
= 0; i
< MAXSUBJECT
; i
++)
fscanf(fp
, "%d", &temp
.data
.score
[i
]);
fscanf(fp
, "%lf", &temp
.data
.aver
);
fscanf(fp
, "%d", &temp
.data
.sum
);
ch
= getc(fp
);
AddFscanf(temp
);
if (ch
== EOF)
break;
}
printf("文件数据读取成功!\n");
fclose(fp
);
}
while (1)
{
Instructions();
switch (choice
)
{
case 1:
AddUserInput();
break;
case 2:
Delete();
break;
case 3:
Inquire();
break;
case 4:
Update();
break;
case 5:
Sort();
break;
case 6:
Save();
break;
case 7:
Print();
break;
case 0:
printf("Bye~ Have a good day! \n\n");
exit(EXIT_FAILURE
);
default:
break;
}
Ask();
}
Free();
return 0;
}
void Free()
{
LIST temp
= headp
->next
;
LIST deletep
= NULL;
while (temp
!= NULL)
{
deletep
= temp
;
temp
= temp
->next
;
free(deletep
);
}
}
void Save()
{
FILE
*fp
= NULL;
int flag
= 0;
LIST temp
= headp
->next
;
if ((fp
= fopen(FileName
, "w")) == NULL)
{
printf("can't open \" %s \" \n", FileName
);
exit(EXIT_FAILURE
);
}
while (temp
!= NULL)
{
if (flag
)
fprintf(fp
, "\n");
fprintf(fp
, "%s ", temp
->data
.name
);
for (i
= 0; i
< MAXSUBJECT
; i
++)
fprintf(fp
, "%d ", temp
->data
.score
[0]);
fprintf(fp
, "%.2f ", temp
->data
.aver
);
fprintf(fp
, "%d", temp
->data
.sum
);
flag
= 1;
temp
= temp
->next
;
}
printf("\n保存成功!");
fclose(fp
);
}
void Sort()
{
LIST temp
= NULL;
STUDENT t
;
int lenth
= 0, j
;
if (headp
->next
== NULL)
{
printf("数据为空!仅可进行写入操作!\n");
return;
}
temp
= headp
->next
;
while (temp
!= NULL)
{
lenth
++;
temp
= temp
->next
;
}
for (i
= lenth
- 1; i
> 0; i
--)
{
temp
= headp
->next
;
for (j
= 0; j
< i
; j
++)
{
if (temp
->data
.sum
< temp
->next
->data
.sum
)
{
t
= temp
->data
;
temp
->data
= temp
->next
->data
;
temp
->next
->data
= t
;
}
else if (temp
->data
.sum
== temp
->next
->data
.sum
)
{
if (strcmp(temp
->data
.name
, temp
->next
->data
.name
) > 0)
{
t
= temp
->data
;
temp
->data
= temp
->next
->data
;
temp
->next
->data
= t
;
}
}
temp
= temp
->next
;
}
}
printf("\n排序成功!");
}
void Update()
{
LIST temp
= NULL;
int flag
;
char NAME
[MAXNAME
];
if (headp
->next
== NULL)
{
printf("数据为空!\n");
return;
}
temp
= headp
;
printf("请输入要更新的学生姓名:\n");
while (1)
{
temp
= headp
;
fflush(stdin);
scanf("%s", NAME
);
getchar();
while (temp
!= NULL)
{
if (strcmp(temp
->data
.name
, NAME
) == 0)
break;
temp
= temp
->next
;
}
if (temp
== NULL)
{
printf("错误!库中没有该学生的信息\n");
printf("键入'n'退出该功能,或键入'y'重新输入\n");
while (1)
{
flag
= 0;
scanf("%c", &c
);
getchar();
if (c
== 'y' || c
== 'Y')
{
printf("请重新输入要更新学生的姓名\n");
break;
}
else if (c
== 'n' || c
== 'N')
{
flag
= 1;
break;
}
else
printf("输入非法!请输入'y'或'n',不要输入其它字符\n");
}
if (flag
)
break;
}
else
{
temp
->data
.sum
= 0;
temp
->data
.aver
= 0.0;
printf("请依次输入该学生语文、数学、英语、计算机、C语言,五门课的成绩\n");
for (i
= 0; i
< MAXSUBJECT
; i
++)
{
scanf("%d", &temp
->data
.score
[i
]);
temp
->data
.sum
+= temp
->data
.score
[i
];
}
temp
->data
.aver
= temp
->data
.sum
* 1.0 / MAXSUBJECT
;
printf("\n更新成功!");
break;
}
}
}
void Inquire()
{
LIST temp
= NULL;
int flag
;
char NAME
[MAXNAME
];
if (headp
->next
== NULL)
{
printf("数据为空!\n");
return;
}
temp
= headp
;
printf("请输入要查询的学生姓名:\n");
while (1)
{
temp
= headp
;
fflush(stdin);
scanf("%s", NAME
);
getchar();
while (temp
!= NULL)
{
if (strcmp(temp
->data
.name
, NAME
) == 0)
break;
temp
= temp
->next
;
}
if (temp
== NULL)
{
printf("错误!库中没有该学生的信息\n");
printf("键入'y'重新输入或'n'退出该功能\n");
while (1)
{
flag
= 0;
scanf("%c", &c
);
getchar();
if (c
== 'y' || c
== 'Y')
{
printf("请重新输入要查询学生的姓名\n");
break;
}
else if (c
== 'n' || c
== 'N')
{
flag
= 1;
break;
}
else
printf("输入非法!请输入'y'或'n',不要输入其它字符\n");
}
if (flag
)
break;
}
else
{
printf("\n\n%s的信息如下:\n\n", NAME
);
printf("%-10s %-8s %-10s %-10s %-10s %-10s %6s\n",
s2
, s3
, s4
, s5
, s6
, s7
, s8
);
printf("%-10.2f %-10d",
temp
->data
.aver
, temp
->data
.sum
);
for (i
= 0; i
< MAXSUBJECT
; i
++)
printf("%-12d", temp
->data
.score
[i
]);
printf("\n");
break;
}
}
}
void Delete()
{
LIST temp
= NULL, deletp
= NULL;
int flag
;
char NAME
[MAXNAME
];
if (headp
->next
== NULL)
{
printf("数据为空!\n");
return;
}
temp
= headp
;
printf("请输入要删除的学生的姓名:\n");
while (1)
{
temp
= headp
;
fflush(stdin);
scanf("%s", NAME
);
getchar();
while (temp
->next
!= NULL)
{
if (strcmp(temp
->next
->data
.name
, NAME
) == 0)
break;
temp
= temp
->next
;
}
if (temp
->next
== NULL)
{
flag
= 0;
printf("您要删除的学生不存在,键入'y'重新输入或'n'退出该功能\n");
while (1)
{
c
= getchar();
getchar();
if (c
== 'y' || c
== 'Y')
{
printf("请重新输入学生姓名:\n");
break;
}
else if (c
== 'n' || c
== 'N')
{
flag
= 1;
break;
}
else
printf("输入非法!请重新输入'y' or 'n'\n");
}
if (flag
)
break;
}
else
{
if (temp
->next
->next
== NULL)
{
free(temp
->next
);
temp
->next
= NULL;
}
else
{
deletp
= temp
->next
;
temp
->next
= temp
->next
->next
;
free(deletp
);
}
printf("\n删除成功!");
break;
}
}
}
void Ask()
{
fflush(stdin);
printf("\n\n输入'n'结束该信息管理系统,或输入其它任意字符回到菜单\n");
scanf("%c", &c
);
getchar();
if (c
== 'n')
{
printf("\nBye~ Have a good day! \n\n");
exit(EXIT_FAILURE
);
}
}
void AddUserInput()
{
int flag
= 0, flag2
= 0;
LIST newp
= NULL;
LIST temp
= headp
->next
;
printf("请输入学生姓名:\n");
while (1)
{
newp
= (LIST
)malloc(sizeof(NODE
));
flag
= 0;
temp
= headp
->next
;
fflush(stdin);
scanf("%s", newp
->data
.name
);
getchar();
while (temp
!= NULL)
{
if (strcmp(newp
->data
.name
, temp
->data
.name
) == 0)
{
flag
= 1;
break;
}
temp
= temp
->next
;
}
if (flag
)
{
printf("\n库中已有该名字,请退回到菜单选择\"更新信息\"或选择重新输入名字\n");
printf("是否重新输入?(y/n)\n");
while (1)
{
flag2
= 0;
c
= getchar();
getchar();
if (c
== 'y')
{
printf("\n您选择了'y',请重新输入名字\n");
break;
}
else if (c
== 'n')
{
flag2
= 1;
break;
}
else
{
printf("\n请输入'y'或'n',不要输入其它字符!\n");
printf("请重新输入'y'或'n' \n");
}
}
if (flag2
)
break;
}
else
{
temp
= headp
;
while (temp
->next
!= NULL)
temp
= temp
->next
;
temp
->next
= newp
;
newp
->next
= NULL;
newp
->data
.sum
= 0;
newp
->data
.aver
= 0.0;
printf("请依次输入该学生语文、数学、英语、计算机、C语言,五门课的成绩\n");
for (i
= 0; i
< MAXSUBJECT
; i
++)
{
scanf("%d", &newp
->data
.score
[i
]);
newp
->data
.sum
+= newp
->data
.score
[i
];
}
newp
->data
.aver
= newp
->data
.sum
* 1.0 / MAXSUBJECT
;
printf("\n添加成功!\n");
printf("是否继续添加?(输入'n'结束该功能,输入其它任意字符继续添加)\n");
fflush(stdin);
c
= getchar();
getchar();
if (c
== 'n')
break;
else
printf("\n请继续输入要添加的学生的姓名\n");
}
}
}
void AddFscanf(NODE newNode
)
{
LIST newp
= (LIST
)malloc(sizeof(NODE
));
LIST temp
= headp
;
while (temp
->next
!= NULL)
temp
= temp
->next
;
temp
->next
= newp
;
newp
->next
= NULL;
newp
->data
.sum
= 0;
newp
->data
.aver
= 0.0;
strcpy(newp
->data
.name
, newNode
.data
.name
);
for (i
= 0; i
< MAXSUBJECT
; i
++)
newp
->data
.score
[i
] = newNode
.data
.score
[i
];
newp
->data
.sum
= newNode
.data
.sum
;
newp
->data
.aver
= newNode
.data
.aver
;
}
void Print()
{
LIST temp
= NULL;
if (headp
->next
== NULL)
{
printf("数据为空!\n");
return;
}
temp
= headp
;
printf("已存储的数据为:\n");
SplitLine();
printf("%-15s %-10s %-8s %-10s %-10s %-10s %-10s %6s\n",
s1
, s2
, s3
, s4
, s5
, s6
, s7
, s8
);
while (temp
->next
!= NULL)
{
printf("%-15s %-10.2f %-10d",
temp
->next
->data
.name
, temp
->next
->data
.aver
,
temp
->next
->data
.sum
);
for (i
= 0; i
< MAXSUBJECT
; i
++)
printf("%-12d", temp
->next
->data
.score
[i
]);
printf("\n");
temp
= temp
->next
;
}
SplitLine();
}
void SplitLine()
{
printf("\n========================================================================================\n\n");
}
void Instructions()
{
printf("\n\n\t The Student's Grade Management System\n\n");
printf("---------------------Student Menu------------------------\n");
if (headp
->next
== NULL)
{
printf("* 1 输入学生信息\t\t\t * 0 退出学生系统\n");
printf("----------------------------------------------------------\n");
printf("此时数据为空!仅支持输入学生信息!\n");
printf("Enter your choice 0 or 1: ");
}
else
{
printf("* 1 输入学生信息\t\t\t * 2 删除学生信息\n");
printf("* 3 查询学生信息\t\t\t * 4 更新学生信息\n");
printf("* 5 排序学生信息\t\t\t * 6 保存学生信息\n");
printf("* 7 显示学生信息\t\t\t * 0 退出学生系统\n");
printf("----------------------------------------------------------\n");
printf("Enter your choice [0 - 9]: ");
}
scanf("%d", &choice
);
printf("\n\n");
}