ADD 实现了对二进制文件的写入、查找、修改、显示学生信息等操作,但删除操作还尚未完成

main
pq52sx6n8 2 months ago
parent af8a4590e9
commit 3e002e3321

@ -0,0 +1,579 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int rank; // 排名序号
char num[20]; // 学号
char name[10]; // 姓名
int math_score; // 高数成绩
int datastruct_score; // 数据结构成绩
int English_score; // 英语成绩
int physics_score; // 物理成绩
float average; // 平均分
} Student;
typedef struct {
Student *data;
int length;
} funlist;
// 初始化线性表
void initlist(funlist *l) {
l->data = (Student *)malloc(100 * sizeof(Student));
l->length = 0;
}
// 判断是否为空表
int isempty(funlist *l) {
return l->length == 0;
}
// 取值
int getelem(funlist l, int i, Student *e) {
if (i < 1 || i > l.length) {
printf("位置不合法\n");
return 0;
}
*e = l.data[i - 1];
return 1;
}
//输出一定数量的空格
void printspace(){
int i;
for(i=0;i<60;i++){
printf(" ");
}
}
// 计算平均分
float calculate_average(Student *s) {
return (s->math_score + s->datastruct_score + s->English_score + s->physics_score) / 4.0f;
}
// 查找操作(按学号查找)二进制文件
int find_by_num(char *num) {
struct student_type{
int rank; // 排名序号
char num[20]; // 学号
char name[10]; // 姓名
int math_score; // 高数成绩
int datastruct_score; // 数据结构成绩
int English_score; // 英语成绩
int physics_score; // 物理成绩
float average; // 平均分
} Student;
FILE *fp;
if((fp=fopen("Z:\\C语言\\数据结构\\studinfo.dat","rb+"))==NULL){
printf("cannot open file\n");
return 0;
}
while(!feof(fp))
{
if(fread(&Student,sizeof(struct student_type),1,fp))
{
if(strcmp(num,Student.num)==0)
{
printf("这个学生的信息为:\n");
printf("学号:%-20s 姓名:%-10s 高数:%-3d 数据结构:%-3d 英语:%-3d 物理:%-3d 平均分:%-4.2f\n",Student.num,Student.name,Student.math_score,Student.datastruct_score,Student.English_score,Student.physics_score,Student.average);
system("pause");
fclose(fp);
return 0;
}
}
}
printf("该学生信息不存在!\n");
fclose(fp);
return 0;
}
// 查找操作(按姓名查找)二进制文件
int find_by_name(char *name) {
struct student_type{
int rank; // 排名序号
char num[20]; // 学号
char name[10]; // 姓名
int math_score; // 高数成绩
int datastruct_score; // 数据结构成绩
int English_score; // 英语成绩
int physics_score; // 物理成绩
float average; // 平均分
} Student;
FILE *fp;
if((fp=fopen("Z:\\C语言\\数据结构\\studinfo.dat","rb+"))==NULL){
printf("cannot open file\n");
return 0;
}
while(!feof(fp))
{
if(fread(&Student,sizeof(struct student_type),1,fp))
{
if(strcmp(name,Student.name)==0)
{
printf("这个学生的信息为:\n");
printf("学号:%-20s 姓名:%-10s 高数:%-3d 数据结构:%-3d 英语:%-3d 物理:%-3d 平均分:%-4.2f\n",Student.num,Student.name,Student.math_score,Student.datastruct_score,Student.English_score,Student.physics_score,Student.average);
system("pause");
fclose(fp);
return 0;
}
}
}
printf("该学生信息不存在!\n");
fclose(fp);
return 0;
}
//显示所有信息
void display()
{
struct student_type{
int rank; // 排名序号
char num[20]; // 学号
char name[10]; // 姓名
int math_score; // 高数成绩
int datastruct_score; // 数据结构成绩
int English_score; // 英语成绩
int physics_score; // 物理成绩
float average; // 平均分
} Student;
FILE *fp;
int i;
if((fp=fopen("E:\\dev-c++\\学生成绩信息.txt","r+"))==NULL){
printf("cannot open file\n");
return;
}
while(!feof(fp))
{
fscanf(fp,"%d%s%s%d%d%d%d%f\n",&Student.rank,Student.num,Student.name,&Student.math_score,&Student.datastruct_score,&Student.English_score,&Student.physics_score,&Student.average);
printf("排名:%d 学号:%s 姓名:%s 高数:%d 数据结构:%d 英语:%d 物理:%d 平均分:%.2f\n",Student.rank,Student.num,Student.name,Student.math_score,Student.datastruct_score,Student.English_score,Student.physics_score,Student.average);
}
fclose(fp);
}
//修改操作(按学号修改) (studinfo.dat二进制文件内容
int revisestudinfo_by_num(char *num){
struct student_type{
int rank; // 排名序号
char num[20]; // 学号
char name[10]; // 姓名
int math_score; // 高数成绩
int datastruct_score; // 数据结构成绩
int English_score; // 英语成绩
int physics_score; // 物理成绩
float average; // 平均分
} Student;
FILE *fp;
long offset=0; //定义一个变量offset,用于存放文件位置标记的偏移量
if((fp=fopen("Z:\\C语言\\数据结构\\studinfo.dat","rb+"))==NULL){ //对二进制文件进行读写操作
printf("cannot open file\n");
return 0;
}
while(!feof(fp))
{
if(fread(&Student,sizeof(struct student_type),1,fp))
{
if(strcmp(num,Student.num)==0)
{
printf("原来这个学生的信息为:\n");
printf("学号:%-20s 姓名:%-10s 高数:%-3d 数据结构:%-3d 英语:%-3d 物理:%-3d 平均分:%-4.2f\n",Student.num,Student.name,Student.math_score,Student.datastruct_score,Student.English_score,Student.physics_score,Student.average);
offset=ftell(fp); //获取文件位置标记的当前位置,这个位置的值是一个字节数(从文件开头到当前位置的位移量大小。)
//fseek(fp,-sizeof(struct student_type),SEEK_CUR); //把文件指针定位到这行信息的开头SEEK_CUR常量表示文件末尾位置也可用2表示
fseek(fp,offset-sizeof(struct student_type),SEEK_SET); //把文件指针定位到这行信息的开头SEEK_SET常量表示文件开始位置也可用0表示
printf("请输入修改的信息:\n");
printf("请输入姓名:");
scanf("%s",Student.name);
printf("请输入学号:");
scanf("%s",Student.num);
printf("请输入高数成绩:");
scanf("%d",&Student.math_score);
printf("请输入数据结构成绩:");
scanf("%d", &Student.datastruct_score);
printf("请输入英语成绩:");
scanf("%d", &Student.English_score);
printf("请输入物理成绩:");
scanf("%d", &Student.physics_score);
Student.average=(Student.math_score+Student.datastruct_score+Student.English_score+Student.physics_score)/4.0;
//Student.average=calculate_average(st); //调用calculate_average函数计算平均分
fwrite(&Student,sizeof(struct student_type),1,fp); //重新修改这个学生信息并存入原来位置
printf("修改成功!");
system("pause");
fclose(fp);
return 0;
}
}
}
printf("该学生信息不存在!\n");
fclose(fp);
return 0;
}
//修改操作(按姓名修改) (studinfo.dat二进制文件内容
int revisestudinfo_by_name(char *name){
struct student_type{
int rank; // 排名序号
char num[20]; // 学号
char name[10]; // 姓名
int math_score; // 高数成绩
int datastruct_score; // 数据结构成绩
int English_score; // 英语成绩
int physics_score; // 物理成绩
float average; // 平均分
} Student;
FILE *fp;
long offset=0; //定义一个变量offset,用于存放文件位置标记的偏移量
if((fp=fopen("Z:\\C语言\\数据结构\\studinfo.dat","rb+"))==NULL){ //对二进制文件进行读写操作
printf("cannot open file\n");
return 0;
}
while(!feof(fp))
{
if(fread(&Student,sizeof(struct student_type),1,fp))
{
if(strcmp(name,Student.name)==0)
{
printf("原来这个学生的信息为:\n");
printf("学号:%-20s 姓名:%-10s 高数:%-3d 数据结构:%-3d 英语:%-3d 物理:%-3d 平均分:%-4.2f\n",Student.num,Student.name,Student.math_score,Student.datastruct_score,Student.English_score,Student.physics_score,Student.average);
offset=ftell(fp); //获取文件位置标记的当前位置,这个位置的值是一个字节数(从文件开头到当前位置的位移量大小。)
//fseek(fp,-sizeof(struct student_type),SEEK_CUR); //把文件指针定位到这行信息的开头SEEK_CUR常量表示文件末尾位置也可用2表示
fseek(fp,offset-sizeof(struct student_type),SEEK_SET); //把文件指针定位到这行信息的开头SEEK_SET常量表示文件开始位置也可用0表示
printf("请输入修改的信息:\n");
printf("请输入姓名:");
scanf("%s",Student.name);
printf("请输入学号:");
scanf("%s",Student.num);
printf("请输入高数成绩:");
scanf("%d",&Student.math_score);
printf("请输入数据结构成绩:");
scanf("%d", &Student.datastruct_score);
printf("请输入英语成绩:");
scanf("%d", &Student.English_score);
printf("请输入物理成绩:");
scanf("%d", &Student.physics_score);
Student.average=(Student.math_score+Student.datastruct_score+Student.English_score+Student.physics_score)/4.0;
//Student.average=calculate_average(st); //调用calculate_average函数计算平均分
fwrite(&Student,sizeof(struct student_type),1,fp); //重新修改这个学生信息并存入原来位置
printf("修改成功!");
system("pause");
fclose(fp);
return 0;
}
}
}
printf("该学生信息不存在!\n");
fclose(fp);
return 0;
}
// 删除操作
int deleteelem(int i) {
int j;
if (i < 1 || i > l->length) {
return 0;
}
for (j = i; j < l->length; j++) {
l->data[j - 1] = l->data[j];
}
l->length--;
// 重新调整排名
for (j = i - 1; j < l->length; j++) {
l->data[j].rank = j + 1;
}
return 1;
}
// 插入操作
int listinsert(funlist *l, int i, Student e) {
if (i < 1 || i > l->length + 1) {
printf("位置不合法\n");
return 0;
}
if (l->length >= 100) {
printf("线性表已满\n");
return 0;
}
int j;
for (j = l->length - 1; j >= i - 1; j--) {
l->data[j + 1] = l->data[j];
// 向后移动排名
l->data[j + 1].rank = l->data[j].rank + 1;
}
// 计算并保存平均分
e.average = calculate_average(&e);
e.rank = i;
l->data[i - 1] = e;
l->length++;
return 1; // 返回1表示成功
}
// 按平均分从小到大排序(冒泡法)
void sort_by_average(){
struct student_type{
int rank; // 排名序号
char num[20]; // 学号
char name[10]; // 姓名
int math_score; // 高数成绩
int datastruct_score; // 数据结构成绩
int English_score; // 英语成绩
int physics_score; // 物理成绩
float average; // 平均分
}Stud[100];
FILE *fp;
int record=0;
int i,j;
struct student_type temp;
if((fp=fopen("Z:\\C语言\\数据结构\\studinfo.dat","rb"))==NULL) //打开studinfo.dat文件 以只读方式打开b参数代表二进制文件
{
printf("cannot open file\n");
return;
}
while(!feof(fp))
{
if(fread(&Stud[record],sizeof(struct student_type),1,fp)){
record++;
}
}
for(i=0;i<record-1;i++){
for(j=0;j<record-1-i;j++){
if(Stud[j].average>Stud[j+1].average){
temp=Stud[j];
Stud[j]=Stud[j+1];
Stud[j+1]=temp;
}
}
}
printf("按平均分从小到大排名如下:\n");
for(i=0;i<record;i++)
printf("排名:%-4d 学号:%-20s 姓名:%-10s 高数:%-3d 数据结构:%-3d 英语:%-3d 物理:%-3d 平均分:%-4.2f\n",Stud[i].rank,Stud[i].num,Stud[i].name,Stud[i].math_score,Stud[i].datastruct_score,Stud[i].English_score,Stud[i].physics_score,Stud[i].average);
}
// 将数据写入文件
void write_to_file(funlist l, const char *filename) {
FILE *file = fopen(filename, "a");
if (file == NULL) {
printf("无法打开文件\n");
return;
}
for (int i = 0; i < l.length; i++) {
fprintf(file, "%d %s %s %d %d %d %d %.2f\n",
l.data[i].rank, l.data[i].num, l.data[i].name, l.data[i].math_score,
l.data[i].datastruct_score, l.data[i].English_score,
l.data[i].physics_score, l.data[i].average);
}
fclose(file);
printf("数据已成功写入文件 %s\n", filename);
}
// 将数据添加到二进制文件文件名为studinfo.dat
void save_binfile(funlist l, const char *filename) {
FILE *file = fopen(filename, "ab"); //以追加写模式打开二进制文件
if (file == NULL) {
printf("无法打开文件\n");
return;
}
for (int i = 0; i < l.length; i++) {
if(fwrite(&l.data[i],sizeof(Student),1,file)!=1)
printf("file write error\n");
}
fclose(file);
printf("数据已成功写入文件 %s\n", filename);
}
//显示所有信息(studinfo.dat的内容
void liststudinfo()
{
struct student_type{
int rank; // 排名序号
char num[20]; // 学号
char name[10]; // 姓名
int math_score; // 高数成绩
int datastruct_score; // 数据结构成绩
int English_score; // 英语成绩
int physics_score; // 物理成绩
float average; // 平均分
} Student;
FILE *fp;
int i;
if((fp=fopen("Z:\\C语言\\数据结构\\studinfo.dat","rb"))==NULL) //打开studinfo.dat文件 以只读方式打开b参数代表二进制文件
{
printf("cannot open file\n");
return;
}
while(!feof(fp))
{
if(fread(&Student,sizeof(struct student_type),1,fp))
printf("学号:%-20s 姓名:%-10s 高数:%-3d 数据结构:%-3d 英语:%-3d 物理:%-3d 平均分:%-4.2f\n",Student.num,Student.name,Student.math_score,Student.datastruct_score,Student.English_score,Student.physics_score,Student.average);
}
fclose(fp);
}
int main() {
funlist L;
initlist(&L);
int choice;
char num[20];
char name[10];
int math_score;
int datastruct_score;
int English_score;
int physics_score;
int i;
printf("\n");
printspace();printf("********学生信息管理系统********");
printf("\n\n");
printspace();printf("1.显示全部学生信息\n");
printspace();printf("2.添加学生信息\n");
printspace();printf("3.保存添加数据\n");
printspace();printf("4.删除学生信息\n");
printspace();printf("5.通过学号查询学生信息\n");
printspace();printf("6.通过姓名查询学生信息\n");
printspace();printf("7.通过学号修改学生信息\n");
printspace();printf("8.通过姓名修改学生信息\n");
printspace();printf("9.按平均分升序排列\n");
printspace();printf("10.退出系统\n");
printf("\n");
while (1) {
printf("请输入操作选项:");
scanf("%d", &choice);
switch (choice) {
case 1:{
liststudinfo(); //显示全部学生信息 studinfo.dat的内容
printf("\n");
break;
}
case 2: {
Student e;
printf("请输入姓名:");
scanf("%s", name);
strcpy(e.name, name);
printf("请输入学号:");
scanf("%s", num);
strcpy(e.num, num);
printf("请输入高数成绩:");
scanf("%d", &math_score);
e.math_score = math_score;
printf("请输入数据结构成绩:");
scanf("%d", &datastruct_score);
e.datastruct_score = datastruct_score;
printf("请输入英语成绩:");
scanf("%d", &English_score);
e.English_score = English_score;
printf("请输入物理成绩:");
scanf("%d", &physics_score);
e.physics_score = physics_score;
printf("请输入想插入的位置(1-%d):\n", L.length + 1);
scanf("%d", &i);
if (listinsert(&L, i, e)) {
printf("插入成功\n");
} else {
printf("插入失败\n");
}
printf("\n");
break;
}
case 3:{
save_binfile(L, "Z:\\C语言\\数据结构\\studinfo.dat"); // 写入二进制文件
free(L.data);
printf("\n");
break;
}
case 4: {
printf("输入想删除的学生位置:");
scanf("%d", &i);
if (deleteelem(&L, i)) {
printf("删除成功\n");
} else {
printf("删除失败\n");
}
printf("\n");
break;
}
case 5:{
printf("输入待查学生的学号:");
scanf("%s", num);
find_by_num(num);
printf("\n");
break;
}
case 6:{
printf("输入待查学生的姓名:");
scanf("%s", name);
find_by_name(name);
printf("\n");
break;
}
case 7: {
printf("输入想修改的学生学号:");
scanf("%s", num);
revisestudinfo_by_num(num);
printf("\n");
break;
}
case 8: {
printf("输入想修改的学生姓名:");
scanf("%s", name);
revisestudinfo_by_name(name);
printf("\n");
break;
}
case 9: {
sort_by_average();
printf("\n");
break;
}
case 10:{
printf("退出系统\n");
free(L.data);
return 0;
break;
}
default:
printf("无效选项,请重新输入\n");
}
}
}
Loading…
Cancel
Save