c语言怎么设置不重复输入不录入重复学号的学生成绩

// xscjgl.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdlib.h>
#include <string.h>


//定义一个名称为node的结构,类型名称为Node
typedef struct node{
char name[10]; //姓名
int number; //学号
float score1; //英语成绩
float score2; //C语言成绩
//char *name;
struct node * next_node;
}Node;

//菜单显示和选择函数
int menu(){
int xz;
printf("1、学生成绩录入\n");
printf("2、学生成绩修改\n");
printf("3、学生成绩删除\n");
printf("4、学生成绩查询\n");
printf("5、学生成绩打印\n");
printf("6、保存成绩到文件\n");
printf("7、从文件载入成绩\n");
printf("8、删除学生成绩\n");
printf("0、退 出\n");

printf("\n请输入选择(0-5):");
scanf("%d",&xz);
getchar(); //清除回车符

if(xz>=0 && xz<=8)
printf("您的输入是%d\n",xz);
else{
printf("您输入了无效的选项!\n\n");
return -1;
}
return xz;
}

//成绩录入函数
void input_cj(Node *head){
char xz;
Node *p=NULL;//指向链表最后一个节点
Node *new_node=NULL;//指向新建的节点
p=head;
while(p->next_node!=NULL){
p=p->next_node;
}
while(1){
new_node=(Node*)malloc(sizeof(Node)); //新增节点
printf("\n请输入 姓名\n");
gets(new_node->name);
printf("\n请输入 学号,英语成绩,C语言成绩\n");
scanf("%d,%f,%f",&new_node->number,&new_node->score1,&new_node->score2);
getchar(); //清除回车符
p->next_node=new_node;//将新建的节点链接的链表的尾部
new_node->next_node=NULL;//新增节点成为链表的最后一个节点
p=new_node;//p指向链表的最后一个节点
printf("\n还需要继续录入吗(按字符n退出,其他键盘继续)?");
scanf("%c",&xz); //字符输入后面不用getchar清换行符
getchar();//清除回车符
if(xz=='n' || xz=='N')
break;
}
return;
}

//获取成绩数量
int getcount_cj(Node *head){
int count=0;
Node *p=NULL;
p=head->next_node; //第一个有效节点
while(p!=NULL){
count=count+1;
p=p->next_node;
}
return count;
}

//将学号与成绩以二进制的方式写入到文件
void write(Node *head){
FILE *fp; // 文件指针
Node *p=NULL;
p=head->next_node; //第一个有效节点
if(p!=NULL){
fp = fopen("students.dat", "wb");
if(fp == NULL){ // 为了写入数据,打开一个二进制文件
printf("read error!\n");
exit(0);
}
int count=getcount_cj(head);
fwrite(&count, sizeof(int), 1, fp); // 从文件中写一个数据块,写的时候是以二进制形式进行的
while(p!=NULL){
fwrite(p, sizeof(struct node), 1, fp); // 从文件中写一个数据块,写的时候是以二进制形式进行的
p=p->next_node;
}
fclose(fp);
}
}

//从二进制文件中读入学号和成绩
void read(Node *head){
int i,count;
FILE *fp; // 文件指针
Node *p=NULL;
Node *new_node=NULL;
p=head;
if((fp = fopen("students.dat", "rb")) == NULL){ // 为了读入数据,打开一个二进制文件
fclose(fp);
return;
}
fread(&count, 1, sizeof(int), fp); // 从文件中读取一个数据块,读写的时候是以二进制形式进行的

for(i=0;i<count;i++){
Node *new_node=(Node*)malloc(sizeof(Node)); //空节点
fread(new_node, sizeof(struct node), 1, fp); // 从文件中读取一个数据块,读写的时候是以二进制形式进行的
p->next_node=new_node;
p=new_node;
}
return;
}

//获取学生总成绩,返回值非int的函数递给会包conflicting types错误提示
int gettotal(Node *head){
int cj=0;
if(head!=NULL){
float cur_cj=head->score1+head->score2; //当前节点成绩合计
Node *ch=head->next_node;
cj=(int)(cur_cj*100)+gettotal(ch); //递归调用,获取后续节点总成绩
}
return cj;
}

//根据姓名返回节点的父节点
Node* getnode_parent(Node *head,char xm[]){
Node *p=NULL;
Node *pre=NULL;
pre=head;
p=head->next_node;
while(p!=NULL){
if(strcmp(xm,p->name)==0){
break;
}else{
pre=p;
p=p->next_node;
}
}
return pre;
}

//根据姓名返回节点
Node* getnode(Node *head,char xm[]){
Node *p=NULL;
p=head;
while(p!=NULL){
if(strcmp(xm,p->name)==0){
break;
}else{
p=p->next_node;
}
}
return p;
}

//删除学生成绩函数
void delete_cj(Node *head){
Node *p;//要删除的节点的父节点
Node *xm_p;
char xm[10];
char xz;
while(1){
printf("\n\n请输入姓名:");
scanf("%s",xm);
getchar();
if(strlen(xm)>10){
printf("\n姓名长度超过10个字符\n");
continue;
}
p=getnode_parent(head,xm); //获取xm所在节点的父节点函数
if(p!=NULL){
xm_p=p->next_node;//xm_p指向要删除的节点
p->next_node=xm_p->next_node;
free(xm_p);//释放删除节点的内容空间
}else{
//xm所在学生不存在
}
printf("\n还需要继续删除吗(按字符n退出,其他键盘继续)?");
scanf("%c",&xz);
if(xz=='n' || xz=='N')
break;
}
return;
}


//查询学生成绩函数
void find_cj(Node *head){
Node *p;
char xm[10];
char xz;
while(1){
printf("\n\n请输入姓名:");
scanf("%s",xm);
getchar();
if(strlen(xm)>10){
printf("\n姓名长度超过10个字符\n");
continue;
}
p=getnode(head,xm); //调用查询函数
if(p!=NULL){
printf("\n姓名=%s\t学号=%d\t英语成绩=%.2f\tC语言成绩=%.2f\n",p->name,p->number,p->score1,p->score2);
}else{
printf("\n不存在姓名为%s的同学\n",xm);
}
printf("\n还需要继续查询吗(按字符n退出,其他键盘继续)?");
scanf("%c",&xz);
if(xz=='n' || xz=='N')
break;
}
return;
}
//成绩打印函数
void display_cj(Node *head){
Node *p=NULL;
p=head->next_node; //第一个有效节点
printf("\n学生成绩:\n");
while(p!=NULL){
printf("学号=%d,姓名=%s,英语成绩=%.2f,C语言成绩=%.2f\n",p->number,p->name,p->score1,p->score2);
p=p->next_node;
}
float zcj=gettotal(head->next_node);//获取总成绩
if(zcj>0)
zcj=zcj/100;
printf("\n总成绩=%.2f\n",zcj);
printf("\n");
return;
}
//主函数
int main()
{
Node *head=NULL;//定义链表头指针变量head
int xz; //菜单选择编号
head=(Node*)malloc(sizeof(Node)); //空节点
head->next_node=NULL;
while(1){
xz=menu();
switch(xz){
case 1:
input_cj(head);//成绩录入
break;
case 2:
break;
case 3:
break;
case 4:
find_cj(head);//成绩查询
break;
case 5:
display_cj(head);//成绩打印
break;
case 6:
write(head);//保存到文件
break;
case 7:
read(head);//从文件读取
break;
case 8:
delete_cj(head);//删除学生成绩
break;
default:
read(head);//从文件读取
break;
}
if(xz==0){
break;
}
}
printf("程序结束!\n按任意键退出");
getchar();
return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值