编制一个C语言成绩记录簿,每个学生信息包括:学号、姓名、C语言成绩。 具体功能看问题补充

编制一个C语言成绩记录簿,每个学生信息包括:学号、姓名、C语言成绩。

具体功能:

1) 读取磁盘文件并显示输出所有学生的成绩;(以文件形式存放成绩)

2) 按学号或姓名查询成绩;

3) 添加成绩记录;

4) 修改指定姓名或学号的学生的成绩并可存盘;
显示输出60分以下、60~79、80~89、90分以上各分数段的学生信息

// 某班级学生C语言第一次正考的成绩存于数据文件score.dat中,记录了学生学号、姓名和考试成绩,bk.dat文件中记录了补考学生的学号、姓名和补考成绩,编写程序以链式存储结构实现以下要求:
// 1、对该班级按成绩降序排序并统计成绩平均分及每个分数段的人数,结果写入到result.dat中。
// 2、再根据补考成绩修改原成绩,修改成绩后仍按成绩降序写在result.dat的后面。成绩修改原则:
// 1)补考成绩大于等于60,原成绩以60分记;2)补考成绩小于60,取两次成绩中最高值记。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 50
typedef struct {
int xh; //学生学号、姓名和考试成绩
char na[MAX];
float cj;
}datatype;

typedef struct Node{
datatype  data;
struct Node* next;
} Seqlist;



void print(Seqlist* l);
void initList(Seqlist  *lp);/*置一个空表*/
void createList(Seqlist  *lp, char strname[]);/*建立成绩顺序表 */
void save(Seqlist  *lp, char strname[]);/*保存学生顺序表到指定文件*/
void sort_cj(Seqlist  *lp);  /*降序排序*/
void average(Seqlist  *lp);  /*算平均分并写入文件 */
void bandscore(Seqlist  *lp);/*划分分数段及写入 */
void changescore(Seqlist  *lp, Seqlist  *bk); /*修改成绩*/

int main()
{
Seqlist  lp, bk;
initList(&lp);  initList(&bk);
createList(&lp, "score.dat");
createList(&bk, "bk.dat");
sort_cj(&lp);
save(&lp, "result.dat");
average(&lp);
bandscore(&lp);
changescore(&lp, &bk);
sort_cj(&lp);
save(&lp, "result.dat");
return 0;
}

/*置一个空表*/
void initList(Seqlist  *lp)
{
lp->next = 0;
lp->data.xh =0;
lp->data.na[0]='\0';
lp->data.cj = 0;
}

void print(Seqlist*l){
Seqlist* p = l->next;
while (p)
{
printf("%d %s %f\n", p->data.xh, p->data.na,p->data.cj);
p = p->next;
}
}
/*建立成绩顺序表 */
void createList(Seqlist  *lp, char strname[])
{
FILE *fp;
int xh;
float cj;
Seqlist*p,*tail=lp;
if ((fp = fopen(strname, "rb")) == NULL)
{
printf("file open error\r\n");
exit(0);
}
while (!feof(fp))
{
p = (Seqlist*)malloc(sizeof(Seqlist));
fscanf(fp, "%d%s%f", &p->data.xh, p->data.na, &p->data.cj);
tail->next = p;
tail = p;


}tail->next = NULL;
 print(lp);
fclose(fp);
}

/*降序排序*/
void sort_cj(Seqlist* head)
{
Seqlist* tail = NULL;
while (tail != head->next)
{
Seqlist* pre = head;
Seqlist* cur = pre->next;
while (cur != tail && cur->next != tail)
{
if (cur->data.cj< cur->next->data.cj)
{
//交换当前节点和后一个节点
pre->next = cur->next;
cur->next = cur->next->next;
pre->next->next = cur;
}
pre = pre->next;
cur = pre->next;
}
tail = cur;
}
}

/*保存学生顺序表到文件(追加)*/
void save(Seqlist *l, char strname[])
{
FILE *fp;
Seqlist *lp= l->next;
int i;
if ((fp = fopen(strname, "ab")) == NULL)
{
printf("file open error\r\n");
exit(0);
}
while (lp){
fprintf(fp, "%d %s %.2f\r\n", lp->data.xh, lp->data.na, lp->data.cj);
lp = lp->next;
}
fprintf(fp, "\r\n");
fclose(fp);
}

/*算平均分并写入文件 */
void average(Seqlist  *l)
{
FILE *fp;
int i,num=0;
Seqlist *lp = l->next;
float s = 0, a;
while (lp){
num++;
s += lp->data.cj;
lp = lp->next;
}
if (num)
a = s / num;
if ((fp = fopen("result.dat", "ab")) == NULL){
printf("file open error\r\n");
exit(0);
}
fprintf(fp, "平均分为%.2f\r\n", a);
fprintf(fp, "\r\n");
fclose(fp);
}

/*分数段及写入 */
void bandscore(Seqlist  *l)
{
FILE *fp;
if ((fp = fopen("result.dat", "ab")) == NULL){
printf("file open error\r\n");
exit(0);
}
Seqlist*lp = l->next;
int i, a = 0, q = 0, w = 0, e = 0, r = 0, t = 0, y = 0;
while (lp){

a = lp->data.cj / 10;
lp = lp->next;
switch (a)
{
case 10:q++; break;
case 9:w++; break;
case 8:e++; break;
case 7:r++; break;
case 6:t++; break;
default:y++; break;
}
}
fprintf(fp, "成绩为100有%d人\r\n", q);
fprintf(fp, "成绩为90~99有%d人\r\n", w);
fprintf(fp, "成绩为80~89有%d人\r\n", e);
fprintf(fp, "成绩为70~79有%d人\r\n", r);
fprintf(fp, "成绩为60~69有%d人\r\n", t);
fprintf(fp, "不及格的有%d人\r\n", y);
fprintf(fp, "\r\n");
fclose(fp);
}


/*修改成绩*/
void changescore(Seqlist  *lp, Seqlist  *bk)
{
int i, j;
Seqlist*la = lp->next, *lb = bk->next;
while (lb){
while (la){
if (lb->data.xh == la->data.xh)
{
if (lb->data.cj >= 60)
la->data.cj = 60;
else if (lb->data.cj > la->data.cj) 
la->data.cj = lb->data.cj;
break;
}
la = la->next;
}
lb = lb->next;
}
print(lp);
}

温馨提示:答案为网友推荐,仅供参考
第1个回答  2014-12-27
#include
#include
#include
int login(char p[16])//登录,密码判断,
{
int w;
char login[16];
printf("请输入密码\n");
gets(login);//输入字符串作为密码
w=strcmp(p,login);//判断两字符串是否相同,若相同则返回0
return w;//返回密码判断的值
}
void display()//菜单
{
printf("*——————————————————————————————————————*\n");
printf("|请选择您所需的操作: |\n");
printf("|——————————————————————————————————————|\n");
printf("|1.输入成绩 2.顺序输出成绩 3.查找最高分 4.查找最低分|\n");
printf("|5.查找特定成绩 6.降序排序成绩 7.求总成绩和平均成绩 |\n");
printf("|8.查找低于特定分数的成绩 9.分段成绩人数及位置 10.增加成绩 |\n");
printf("|11.更改成绩 12.删除单个成绩 13.删除全部成绩 14.修改密码 |\n");
printf("|0.退出 |\n");
printf("*——————————————————————————————————————*\n");
}
int input(double score[200])//输入数据
{
int p,q,i=1;
printf("请输入学生人数\n");
scanf("%d",&p);
for(q=0;q<p;q++)
{
printf("请输入第%d个人成绩\n",i);
scanf("%lf",&score[q]);
i++;
}
printf("输入完毕\n");
return p;//返回总人数
}
void output(double score[200],int x)//顺序输出学生成绩
{
int i=0;
if(x!=0)
while(i!=x)
{
printf("第%d个人的成绩为%lf\n",i+1,score[i]);
i++;
}
else
printf("数据为空,请先输入数据\n");//容错,当数组中没有数据时提示用户先输入数据
}
void max(double score[200],int x)//查询最大成绩
{
int m,n;
double max;
if(x!=0)
{
max=score[0];n=1;
for(m=1;m<x;m++)//循环判断最大成绩与其所在位置,所在位置为下标加1
{
if(max<score[m])
{
max=score[m];
n=m+1;
}
}
printf("最高成绩为%lf,是第%d个\n",max,n);
}
else printf("数据为空,请先输入数据\n");//容错
}
void min(double score[200],int x)//查询最低成绩
{
int m,n;
double min;
if(x!=0)
{
min=score[0];n=1;
for(m=1;m<x;m++)//循环判断最低成绩与其所在位置,所在位置为下标加1
{
if(min>score[m])
{
min=score[m];
n=m+1;
}
}
printf("最低成绩为%lf,是第%d个\n",min,n);
}
else printf("数据为空,请先输入数据\n");//容错
}
void spe(double score[200],double m,int n)//查询特定成绩
{
int i,x=0;
int location[200];
for(i=0;i<n;i++)//循环
if(score[i]==m)//判断是否为所查询的成绩
{
location[x]=i+1;
x++;
}
if(x!=0)
{
printf("您所查询的成绩为%lf,在以下位置出现\n",m);//输出所查询的成绩
for(i=0;i<x;i++)
printf("%d ",location[i]);//输出所查询成绩的所在位置,此位置为下标加1
printf("\n");
}
else
printf("此成绩不存在\n");//容错,当所查询的成绩不存在是输出
}
void down(double score[200],int x)//降序排列
{
int m,n;
double temp;
if(x!=0)
{
for(m=0;m<x;m++)//选择排序,控制第一个数
for(n=m+1;n<x;n++)//选择排序,控制第二个数
if(score[m]<score[n])//判断,当后面的数比前面的小时两数交换位置
{
temp=score[m];
score[m]=score[n];
score[n]=temp;
}
printf("降序排列为\n");
n=1;
for(m=0;m<x;m++)//输出控制,每行只输出4个数
{
printf("%lf ",score[m]);
n++;
if(n==5)//输出控制,用于判断回车符的输出
{
n=1;
printf("\n");
}
}
}
else printf("数据为空,请先输入数据\n");//容错
}
double ave(double score[200],int x)//输出总分与平均分
{
double sum=0,ave0;
int i;
if(x!=0)
{
for(i=0;i<x;i++)//累加求和,求出总分
sum=sum+score[i];
ave0=sum/x;//求出平均分
printf("总成绩为%lf\n",sum);
return ave0;
}
else
{
printf("数据为空,请先输入数据\n");//容错
return 0;
}

}
void fil(double score[200],double w,int x)//输出小于特定分数的成绩所在位置,位置为下标加1
{
int i,m;
int location[200];
for(i=0;i<x;i++)
if(score[i]<w)
{
location[m]=i+1;
m++;
}
if(m!=0)
{
printf("所查询的成绩在以下位置出现\n");
for(i=0;i<m;i++)
printf("%d ",location[i]);
}
else
printf("此成绩不存在\n");
}
void sec(double score[200],int x)//成绩分段并输出各段人数与位置,位置为下标加1
{
int s,i=0,m=0,n=0,s80[200],s60[200],s0[200],f=1;
if(x!=0)
{
for(s=0;s<x;s++)//循环判断各成绩所在段
{
if(score[s]>=80)
{
s80[i]=s+1;
i++;
}
else
if(score[s]>=60)
{
s60[m]=s+1;
m++;
}
if(score[s]<60)
{
s0[n]=s+1;
n++;
}
}
printf("80分至100分的人数为%d,在以下位置出现\n",i);//输出各段的人数
for(s=0;s<i;s++)
{
printf("%d ",s80[s]);
if(f==10)
{
printf("\n");
f=1;
}
}
printf("\n60分至80分的人数为%d,在以下位置出现\n",m);
f=1;
for(s=0;s<m;s++)
{
printf("%d ",s60[s]);
if(f==10)
{
printf("\n");
f=1;
}
}
printf("\n60分以下的人数为%d,在以下位置出现\n",n);
f=1;
for(s=0;s<n;s++)
{
printf("%d ",s0[s]);
if(f==10)
{
printf("\n");
f=1;
}
}
}
else
printf("数据为空,请先输入数据\n");//容错
}
int add(double score[200],int x,double y,int z)
{
int i;
for(i=z;i>=x;i--)
score[i]=score[i-1];
score[x-1]=y;
printf("增加成功\n");
return 1;
}
void rejigger(double score[200],int x,double y)
{
score[x-1]=y;
printf("更改成功\n");
}
void del(double score[200],int x,int y)
{
int i;
for(i=x;i<y;i++)
score[i-1]=score[i];
score[y]=0;
}
int format(double score[200])
{
int i;
char validate;
printf("是否确认删除所有数据Y/N\n");
scanf("%c",&validate);
scanf("%c",&validate);
if(validate=='Y'||validate=='y')
{
for(i=0;i<200;i++)
score[i]=0;
printf("删除成功\n");
return 1;
}
else
{
printf("取消删除\n");
return 0;
}
}

void main()
{
char password[16]="123456";//定义默认密码
double score[200],m,n,w,z;
int choose,x=3,i,f,b=0,change=1,y;
char *p,validate;
double *a;
int flag = 0;
p = password;
a=score;
f=3;i=0;
while(f)//密码错误次数控制,当错误时重新输入,若连续错误3次则直接退出程序
{
i=login(password);
if(i)
{
x--;
if(x>0)
printf("密码错误,请重新输入,您还有%d次机会\n",x);
else
{
printf("密码错误,程序自动退出\n");
exit(1);
}
f--;//次数控制
continue;
}
else//当密码输入正确时进入下一步
{
flag = 1;
break;
}
}
while(flag)//主循环,控制菜单的循环输出与程序的循环使用
{
display();//输出菜单
scanf("%d",&choose);//功能选择
switch(choose)//功能判断
{
case 1:b=input(score);break;//输入成绩
case 2://顺序输出成绩
output(score,b);
break;
case 3:max(score,b);break;//输出最大值
case 4:min(score,b);break;//输出最小值
case 5://查询特定成绩
if(b!=0)
{
printf("请输入要查询的成绩\n");
scanf("%lf",&m);
spe(score,m,b);
}
else
printf("数据为空,请先输入数据\n");
break;
case 6:down(score,b);break;//降序排列
case 7:n=ave(score,b);printf("平均成绩为%lf\n",n);break;//输出总成绩与平均成绩
case 8://查询低于特定分数的成绩
if(b!=0)
{
printf("请输入分数\n");
scanf("%lf",&w);
fil(score,w,b);
}
else
printf("数据为空,请先输入数据\n");
break;
case 9:sec(score,b);break;//成绩分段
case 10:
if(b!=0)
{
printf("请输入要增加的成绩和所在位置\n");
scanf("%lf%d",&z,&y);
add(score,y,z,b);
b=b+1;
}
else
printf("数据为空,请先输入数据\n");
break;
case 11:
if(b!=0)
{
printf("请输入要修改的位置和修改后的成绩\n");
scanf("%d%lf",&y,&z);
rejigger(score,y,z);
}
else
printf("数据为空,请先输入数据\n");
break;
case 12:
if(b!=0)
{
printf("请输入要删除的位置\n");
scanf("%d",&y);
del(score,y,b);
b=b-1;
}
else
printf("数据为空,请先输入数字\n");
break;
case 13:
y=format(score);
if(y==1) b=0;
break;

case 0:
printf("程序退出后所有数据将消失,确定退出程序?Y/N\n");
scanf("%c",&validate);
scanf("%c",&validate);
if(validate=='Y'||validate=='y') flag=0;//退出
}
}
printf("谢谢使用\n");
}
相似回答