复制内容到剪贴板
代码:
#include<stdio.h>
#include<string.h>
#define M 18 //线性表长
#define B 3 // 将线性表分成B块
#define S 6 // 每块内结点数为S
typedef char keytype; //定义关键字类型是字符型
typedef char datatype;
typedef struct //学生的结点结构
{
char num[8],name[10],mima[8]; //学生的学号,姓名 ,密码
int chin,phy,chem,eng; //学生的年龄,中文、物理、化学和英语成绩
}STUDENT;
typedef struct //线性表的结点结构
{
keytype key[8]; //关键字
STUDENT stu;
}TABLE;
typedef struct //索引表的结点结构
{
keytype key[8];
int low,high;
}INDEX;
TABLE list[M]; // 说明线性表变量
INDEX inlist[B]; // 索引表变量
void readtxt(void) // 构造线性表list及索引表inlist
{
FILE *fp;
int i,d;
char max[8];
fp=fopen("score.txt","r"); //以只读方式打开SCORE.TXT文件
for(i=0;i<M;i++) // 将SCORE.TXT中的M个数据输到线性表list中
{
fscanf(fp,"%s",list[i].stu.num);//从文件SCORE.TXT中输入第i个学生的学号
fscanf(fp,"%s",list[i].stu.mima);//从文件SCORE.TXT中输入第i个学生的密码
fscanf(fp,"%s",list[i].stu.name); //从SCORE.TXT中输入第i个学生的姓名
fscanf(fp,"%d",&list[i].stu.chin); //从SCORE.TXT中输入第i生的中文成绩
fscanf(fp,"%d",&list[i].stu.phy); //从SCORE.TXT中输入第i生的物理成绩
fscanf(fp,"%d",&list[i].stu.chem); //从SCORE.TXT中输入第i生的化学成绩
fscanf(fp,"%d",&list[i].stu.eng); //从SCORE.TXT中输入第i生的英语成绩
strcpy(list[i].key,list[i].stu.num); //将第i个学生的学号设为关键字
}
for(i=0;i<B;i++) // 构造索引表inlist,B是线性表的块数
{
inlist[i].low=i+(i*(S-1)); // 每块内结点数为S
inlist[i].high=i+(i+1)*(S-1);
}
strcpy(max,list[0].stu.num);//将第0个学生的学号复制到数组max中
d=0;
for(i=1;i<M;i++)
{
if(strcmp(max,list[i].stu.num)<0) //串max小于串list[i].stu.num
strcpy(max,list[i].stu.num); //将大的串放到max中,这是在线性表的一块中找
if((i+1)%6 == 0)
{
strcpy(inlist[d].key,max);
d++; //将索引表中第d个元素的inlist[d].key
if(i<M-1) //设为线性表中第d个块的学号的最大值
strcpy(max,list[i+1].stu.num);//将线性表中的下一块的第一个学生的学号
i++; //复制到max中,去求该块中的最大学号
}
}
fclose(fp); // 关闭SCORE.TXT文件
}
void modify(char *key,int kc,int cj) //kc是课程号,cj是成绩,key是要找的学号
{
int low1=0,high1=B-1,mid1,mid2,i,j;
int flag=0;
while(low1<=high1&&!flag)
{
mid1=(low1+high1)/2; //在索引表中求中间块位置
if(strcmp(inlist[mid1].key,key)==0)//中间块的关键字值与要找的键值相比较
{
flag=1; //找到了
mid2=mid1;
}
else if(strcmp(inlist[mid1].key,key)>0) //到前边的块内查找
high1=mid1-1;
else
low1=mid1+1; //到后边的块内查找
}
if(low1<B) //以下是在所找到的块内查找
{
i=inlist[low1].low;
j=inlist[low1].high;
}
if(mid2==1)
{
i=inlist[1].low;
j=inlist[1].high;
}
while(i<j&&strcmp(list[i].key,key))
i++; //在块内找学号相符的学生,可能找到,也可能找不到
if(strcmp(list[i].key,key)==0) //找到了,根据所给的学号去修改相应的成绩
if(kc==1)
list[i].stu.chin=cj;
else if(kc==2)
list[i].stu.phy=cj;
else if(kc==3)
list[i].stu.chem=cj;
else if(kc==4)
list[i].stu.eng=cj;
}
void writetxt(void)
{
FILE *fp; int i;
fp=fopen("score.txt","w"); // 以写方式打开SCORE.TXT文件
for(i=0;i<M;i++) // 将修改后的数据输出到SCORE.TXT文件中
{
fprintf(fp,"%s ",list[i].stu.num);
fprintf(fp,"%s ",list[i].stu.mima);
fprintf(fp,"%s",list[i].stu.name);
fprintf(fp,"%4d",list[i].stu.chin);
fprintf(fp,"%4d",list[i].stu.phy);
fprintf(fp,"%4d",list[i].stu.chem);
fprintf(fp,"%4d",list[i].stu.eng);
fprintf(fp,"\n");
}
fclose(fp); // 关闭SCORE.TXT文件
}
void printtxt(void) // 打印文件中的数据
{
int i;
printf(" 学号 姓名 语文 物理 化学 英语\n");
for(i=0;i<M;i++)
{
printf("%s ",list[i].stu.num);
printf("%s ",list[i].stu.name);
printf("%4d",list[i].stu.chin);
printf("%5d",list[i].stu.phy);
printf("%5d",list[i].stu.chem);
printf("%5d",list[i].stu.eng);
printf("\n");
}
}
void main( )
{
int t,k;
int T=0,T1=0,T2=0; // 字符数组比较时的标志
int kc,cj;
char key[8],mima[8],mm[8];
char Mima[8]="tang"; //老师查看成绩和修改成绩的密码
printf(" ****************************************\n");
printf(" \n 学生成绩操作的菜单选择系统 \n \n");
printf(" ****************************************\n");
printf(" \n你可以进行的操作如下:\n\n");
printf(" =================================\n\n");
printf(" 1. 老师查看学生的成绩\n");
printf(" 2. 学生查看自己的成绩\n");
printf(" 3. 老师修改学生的成绩\n");
printf(" 4. 退出学生成绩的操作\n");
printf(" \n =================================\n");
printf("\n 请选择你要进行的操作,选择操作号(1--4):\t");
for(; ;)
{ scanf("%d",&t);
if(t<1|| t>4)
printf("\n\t操作号输人错误,重新输入(1--4): \t");
else
break;
}
do
{switch(t)
{
case 1:
printf("\n 1. 老师查看所有学生的成绩\n");
fflush(stdin); //把缓冲区清空
printf("\n 请输入老师的密码:\t");
gets(mima);
while(strcmp(mima,Mima)!=0)
{
printf("\n 密码输入错误,请重输:\t");
gets(mima);
}
printf("\n 密码输入正确!\n");
printf("\n 学生成绩如下:\n\n");
readtxt(); // 调用输入数据函数
printtxt(); // 打印文件中的数据
break;
case 2:
printf("\n 2. 学生查看自己的成绩\n");
fflush(stdin); //把缓冲区清空
readtxt(); // 调用输入数据函数
printf("\n 请输入学生的学号:\t");
gets(key);
do
{
for(int i=0;i<M;i++)
{
if(strcmp(list[i].key,key)==0)
{
T=1;
k=i;
break;
}
}
if(T==0)
{
fflush(stdin); //把缓冲区清空
printf("\n 学生学号输入错误!\t");
printf("\n 请重输学生的学号:\t");
gets(key);
}
}while(T==0);
fflush(stdin);
printf("\n 请输入学生的密码:\t");
gets(mm);
do
{
if(strcmp(list[k].stu.mima,mm)==0)
T2=1;
else
{
printf("\n 学生密码输入错误!\t");
printf("\n 请重输学生的密码:\t");
gets(mm);
}
}while(T2==0);
if(T==1)
{
printf("\n");
printf(" 学号 姓名 语文 物理 化学 英语\n");
printf("%s",list[k].stu.num);
printf("%5s",list[k].stu.name);
printf("%5d",list[k].stu.chin);
printf("%5d",list[k].stu.phy);
printf("%5d",list[k].stu.chem);
printf("%5d",list[k].stu.eng);
printf("\n");
}
break;
case 3:
printf("\n 3. 老师修改学生的成绩\n");
fflush(stdin); //把缓冲区清空
readtxt(); // 调用输入数据函数
printf("\n 请输入老师的密码:\t");
gets(mima);
while(strcmp(mima,Mima)!=0)
{
printf("\n 密码输入错误,请重输:\t");
gets(mima);
}
printf("\n请输入欲修改成绩的学号:\t");
gets(key);
do
{
for(int i=0;i<M;i++)
{
if(strcmp(list[i].key,key)==0)
{
T1=1;
k=i;
break;
}
}
if(T1==0)
{
fflush(stdin); //把缓冲区清空
printf("\n 学生学号输入错误!\t");
printf("\n 请重输学生的学号:\t");
gets(key);
}
}while(T1==0);
if(T1==1)
{
printf("\n");
printf(" 学号 姓名 语文 物理 化学 英语\n");
printf("%s",list[k].stu.num);
printf("%5s",list[k].stu.name);
printf("%5d",list[k].stu.chin);
printf("%5d",list[k].stu.phy);
printf("%5d",list[k].stu.chem);
printf("%5d",list[k].stu.eng);
printf("\n");
}
printf("\n选择欲修改成绩的课程编号:语文(1)物理(2)化学(3)英语(4):\t");
scanf("%d",&kc);
while(kc!=1&&kc!=2&&kc!=3&&kc!=4)
{
printf("\n 学生成绩的课程编号输入错误!\n");
printf("\n 请重输学生成绩的课程编号:\t");
scanf("%d",&kc);
}
printf("\n输入该课程的修改成绩:\t");
scanf("%d",&cj);
modify(key,kc,cj); // 调用分块查找及数据修改函数
writetxt(); // 调用输出数据函数
break;
case 4:
printf("\n 4. 退出查找的操作\n\n");
printf(" 再 见 !!\t\n");
break;
}
if(t==4) break;
printf("\n 请选择你要进行的操作,选择操作号(1--4):\t");
scanf("%d",&t);
if(t!=1&&t!=2&&t!=3&&t!=4)
{
printf("\n 操作号输入错误:");
}
}while(t!=1||t!=2||t!=3||t!=4);
}