// 学生信息录入系统2.0
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include<conio.h>
#include<Windows.h>
#include<process.h>
#define MaxStu 100
#define FILENAME "students.dat" //M103
typedef struct stu { //M104 起别名
char id[16]; //学号
char name[16]; //姓名
short sex; //M101 性别 -1为默认值 0表示男 1表示女
int age; //年龄
char tel[16]; //手机号码
}*STU;
typedef struct stu_proj { //M104
struct stu students[MaxStu]; //学生数组,最大值是MaxStu,采用散列表的形式存储;
int exist[MaxStu]; //学生是否存在,如果存在则exist[i]=1;
int n; //当前学生数;
int isModify; //M134 用来标识记录是否被修改过
}*STU_PROJ;
int _1_enter(STU_PROJ sp); //录入数据
int _2_del(STU_PROJ sp); //删除数据
int _3_update(STU_PROJ sp); //更新数据
int _4_search(STU_PROJ sp); //查找数据
int _5_save(STU_PROJ sp); //保存数据
int _6_load(STU_PROJ sp); //加载数据
int _7_clear(STU_PROJ sp); //清空数据 M105 M109
STU_PROJ init(); //初始化数据 M105 M109
//进行健壮性判断
int ISTURE(STU_PROJ sp) { //M111
if(!sp) {
printf("\t\t数据为空!\n");
getch();
return -1; //参数sp为空,返回-1
} else if(sp->n == MaxStu) {
printf("\t\t学生数已满!\n");
getch();
return 2; //学生数满,返回2;
} else
return 1;
}
//判断学号是否已经存在。
static int HaveId(char *id,STU_PROJ sp) { //M113
int i;
if(ISTURE(sp) == -1) return -1; //如果sp是空指针,返回-1
for(i=0; i<sp->n; i++)
if(strcmp(sp->students[i].id,id) == 0)
return i+1; //已经存在返回下标+1,
return 0; //不存在返回0
}
// 学号查询或录入 确定输入学号的严谨性是正确性
int INID(STU_PROJ sp,char* id) { //M112
int len,i; //len=学号长度
char tmp1[1024]; //用临时数组储存学号 以免异常输入
printf("\t\t请输入十位学号(输入0返回):");
scanf("%s",tmp1); //输入学号
len=strlen(tmp1);
if(strcmp(tmp1,"0") == 0)return -1;
if(len == 10) {
for(i=0; i<10; i++) {
if(tmp1[i] <'0' || tmp1[i] > '9') {
printf("\t\t输入学号错误!\n");
getch();
break;
return 8; //学号并非全是数字返回8;
}
}
strcpy(id,tmp1); //录入学号
if(HaveId(tmp1,sp) !=0 )
return 5; //学号已存在返回5;
else
return 1; //学号正确输入且无重复返回1;
}
else if(len<10)
printf("\t\t输入学号不足十位!\n");
else if(len>10)
printf("\t\t输入学号超过十位!\n");
getch();
return 6; //学号长度错误返回6;
}
//姓名录入 确定输入姓名的严谨性是正确性
int INNAME(char* name) { //M114
int len,i; //len=姓名长度
char tmp1[1024]; //用临时数组储存姓名 以免异常输入
printf("\t\t请输入姓名:");
scanf("%s",tmp1); //输入姓名
len=strlen(tmp1);
if(strcmp(tmp1,"0")==0)return 1; //输入0返回1
else if(strcmp(tmp1,"-1")==0)return 9; //输入-1返回9
else if(len>16) {
printf("\t\t输入错误:输入姓名过长!\n");
getch();
return 7; //输入姓名过长返回7
} else {
strcpy(name,tmp1);
return 16; //正确输入返回16
}
}
//性别录入 确定输入性别的严谨性是正确性
int INSEX(short* sex) { //M116
int len,i; //len=性别长度
char tmp1[1024]; //用临时数组储存性别 以免异常输入
printf("\t\t性别输入方式可以是:(男\\女、0\\1、m\\f、male\\female ) \n\t\t请输入性别:");
scanf("%s",tmp1); //输入性别
if((strcmp(tmp1,"男") == 0 ) || (strcmp(tmp1,"0") == 0 )
|| (strcmp(tmp1,"m") == 0 ) || (strcmp(tmp1,"male") == 0 )) {
*sex=0; //性别为男
} else if((strcmp(tmp1,"女") == 0 ) || (strcmp(tmp1,"1") == 0 )
|| (strcmp(tmp1,"f") == 0 ) || (strcmp(tmp1,"female") == 0 )) {
*sex=1; //性别为女
} else {
printf("\t\t输入错误!\n");
getch();
return 10; //输入错误返回10
}
return 1; //输入正确返回1
}
//手机号码录入 确定输入手机号码的严谨性是正确性
int INTEL(char* tel) { //M118
int len,i; //len=手机号码长度
char tmp1[1024]; //用临时数组储存手机号码 以免异常输入
printf("\t\t请输入手机号码:");
scanf("%s",tmp1); //输入手机号码
len=strlen(tmp1);
if(strcmp(tmp1,"0")==0)return 1; //输入0返回1
else if(strcmp(tmp1,"-1")==0)return 9; //输入-1返回9
else if(len>16) {
printf("\t\t输入错误:输入手机号码过长!\n");
getch();
return 7; //输入错误返回7
} else {
strcpy(tel,tmp1); //手机号码录入
return 16; //正确输入返回16
}
}
//年龄录入 确定输入年龄的严谨性是正确性
int INAGE(int* age) { //M117
char t[1024];
int len,i,temp;
printf("\t\t请输入年龄:");
scanf("%s",t); //临时变量年龄
len=strlen(t);
for(i=0;i<len;i++)
if(t[i] <'0' || t[i] > '9')
return -1; //输入有非数字的
temp=t[0]-'0';
for(i=1;i<len;i++)
temp=t[i]-'0'+temp*10; //数字转换
if(temp>=10 && temp<=60) { //学生年龄必须在10到60之间,必须是数字
*age=temp; //录入年龄
return 1; //正确输入返回1
}else if(temp<10)
printf("\t\t年龄太小\n");
else if(temp>10)
printf("\t\t年龄太大\n");
getch();
return 11; //如果输入错误,函数返回11;
}
int main() {
int i=1,c;
int temp=-2;
STU_PROJ sp; //声明存储学生信息的结构
sp= init(); //M102 调用初始化函数
_6_load(sp); //M102 加载已有数据
do {
system("cls");
printf("\n\n\t\t┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄\n");
printf("\t\t ☆☆ 学生信息管理系统 ☆☆ \n");
printf("\t\t┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐\n");
printf("\t\t┆ ┆\n");
printf("\t\t┆ 0、退出系统 ┆\n");
printf("\t\t┆ ┆\n");
printf("\t\t┆ 1、新增学生信息 ┆\n");
printf("\t\t┆ 2、删除学生信息 ┆\n");
printf("\t\t┆ 3、修改学生信息 ┆\n");
printf("\t\t┆ 4、查询学生信息 ┆\n");
printf("\t\t┆ ┆\n");
printf("\t\t┆ 5、保存学生信息 ┆\n");
printf("\t\t┆ 6、加载学生信息 ┆\n");
printf("\t\t┆ ┆\n");
printf("\t\t┆ 7、清空学生数据 ┆\n");
printf("\t\t├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┤\n");
printf("\t\t┆ ┆\n");
printf("\t\t┆ 开发者:程序路上的小明 版本:V2.0 ┆\n");
printf("\t\t┆ ┆\n");
printf("\t\t└┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘\n");
printf("\n\t\t请选择功能:");
c=getch()-'0';
system("cls");
switch(c) {
case 0:
if(sp->isModify ==1 )
{
printf("\t\t有学生数据是否保存!\n");
printf("\t\t请选择:是\\否(1\\2)\n\t\t");
i=getch()-'0';
if(i==1)temp=_5_save(sp); //M134
}
getch();
return 0;
case 1:
temp=_1_enter(sp);
break;
case 2:
temp=_2_del(sp);
break;
case 3:
temp=_3_update(sp);
break;
case 4:
temp=_4_search(sp);
break;
case 5:
temp=_5_save(sp);
break;
case 6:
temp=_6_load(sp);
if(temp == 0){
printf("\t\t加载成功!\n");
printf("\t\t任意键继续......");
getch();
}
break;
case 7:
temp=_7_clear(sp);
break;
}
} while(c!=0);
}
int _1_enter(STU_PROJ sp) {
int i=sp->n;
int temp;
printf("\t\t 1、新增学生信息 \n");
temp=INID(sp,sp->students[i].id); //录入学号
if(temp==5) {
printf("\t\t该学号已存在!\n");
getch();
return 0; //学号已存在返回0
} else if(temp!= 1) return 0;
if(INNAME( sp->students[i].name) != 16) return 0; //录入姓名
sp->exist[i]=1; //M115
sp->n++; //M115
sp->isModify=1; //M134 标记修改过
if(INSEX( &sp->students[i].sex ) != 1) return 0; //录入性别
if(INAGE( &sp->students[i].age) != 1) return 0; //录入年龄
if(INTEL(sp->students[i].tel) != 16) return 0; //录入手机号码
printf("\t\t输入成功!\n");
printf("\t\t任意键继续......");
getch();
return 0;
}
int _2_del(STU_PROJ sp) {
int i,t=0;
char id[20];
printf("\t\t 2、删除学生信息 \n");
if(!sp)return -1; //M120
if(sp->n==0) return 3; //M120
t=INID(sp,id);
if(t == -1) return 1; //M120
if(t == 6 ) return 2;
if(t != 5 ) { //M122 INID函数已内嵌HaveId函数
printf("\t\t学号不存在!\n");
getch();
return 0;
}
for(i=0; i<MaxStu; i++) //M121 删除并对数据重新设置默认值
if( strcmp(sp->students[i].id,id) == 0) {
sp->exist[i]=0;
printf("\t\t删除成功!\n");
break;
}
for(i; i<MaxStu-1; i++)
sp->students[i]=sp->students[i+1]; //删除该学生
//初始化数据
sp->exist[MaxStu-1] = 0;
sp->students[MaxStu-1].age = -1;
sp->students[MaxStu-1].id[0] = -1;
sp->students[MaxStu-1].name[0] = -1;
sp->students[MaxStu-1].sex = -1;
sp->students[MaxStu-1].tel[0] = -1;
sp->n--;
sp->isModify=1; //M134
printf("\t\t任意键继续......");
getch();
return 0;
}
int _3_update(STU_PROJ sp) {
int i,index;
char id[16];
int t;
printf("\t\t 3、修改学生信息 \n");
if(!sp) return -1; //M123 更新函数进行健壮性判断
if(sp->n==0) return 3;
t=INID(sp,id); //M124 修改学生信息先输入学号,要求10位
if(t==8) return 8;
if(t==1) return 4;
index=HaveId(id,sp)-1;
if(index<0) return 0; //学号不存在返回0
if(strcmp(id,"0") == 0) return 1; //M127 输入0放弃修改
printf("\t\t请选择要修改的数据:\n");
printf("\t\t1.学号\n");
printf("\t\t2.姓名\n");
printf("\t\t3.性别\n");
printf("\t\t4.年龄\n");
printf("\t\t5.手机号码\n\t\t");
i=getch()-'0';
printf("\n");
switch(i) { //M125 选择修改
case 0: //M127
return 1;
case 1:
if( INID(sp, sp->students[index].id) == 1 ) //修改学号
printf("\t\t学号修改成功\n");
else
return 0;
break;
case 2:
if( INNAME(sp->students[index].name) == 16) //修改姓名
printf("\t\t姓名修改成功\n");
else
return 0;
break;
case 3:
if( INSEX(&sp->students[index].sex) == 1) //修改性别
printf("\t\t性别修改成功\n");
else
return 0;
break;
case 4:
if( INAGE(&sp->students[index].age) == 1) //修改年龄
printf("\t\t性别修改成功\n");
else
return 0;
break;
case 5:
if( INTEL(sp->students[index].tel) == 16) //修改手机号码
printf("\t\t手机号码修改成功\n");
else
return 0;
break;
default:
fflush(stdin); //清空缓存
return 12;
}
sp->isModify=1; //M134
printf("\t\t任意键继续......");
getch();
return 1;
}
int _4_search(STU_PROJ sp) { //M128
int i;
if(!sp || sp->n == 0) return -1; //M130 参数sp为空,返回-1;
printf("\t\t查询结果:\n"); //M129 默认性别显示 男\女
printf("\t\t%-16s%-16s%-16s%-16s%-16s\n","学号","姓名","性别(男\\女)","年龄","手机号码");
for(i=0; i<sp->n; i++) { //格式输出所有学生信息
printf("\t\t%-16s%-16s",sp->students[i].id,sp->students[i].name);
if(sp->students[i].sex == 0)
printf("%-16s","男");
else
printf("%-16s","女");
printf("%-16d%-16s\n",sp->students[i].age,sp->students[i].tel);
}
getch();
return 0;
}
int _5_save(STU_PROJ sp) { //M131 保存函数
if(ISTURE(sp) == -1) return -1;
FILE *fp;
fp=fopen(FILENAME,"wb"); //打开文件
fwrite(sp,sizeof(struct stu_proj),1,fp); //写入文件
fclose(fp);
sp->isModify=0; //M134
printf("\t\t保存成功\n");
printf("\t\t任意键继续......");
getch();
return 1;
}
int _6_load(STU_PROJ sp) { //M132 加载函数
if(ISTURE(sp) == -1)
{
printf("\t\t加载失败!\n");
getch();
return -1;
}
FILE *fp;
fp=fopen(FILENAME,"rb"); //打开文件
fread(sp,sizeof(struct stu_proj),1,fp); //读取文件
fclose(fp);
return 0;
}
int _7_clear(STU_PROJ sp) { //M109 清空学生数据
int temp=0,i;
if(sp->n == 0) {
printf("\t\t无数据!\n\t\t");
getch();
return 1;
} else {
printf("\t\t存在学生数据请选择:\n\t\t<1>直接删除已有数据\n\t\t<2>放弃初始化。\n\t\t");
temp=getch()-'0';
}
if(temp == 2) {
printf("\t\t已取消初始化\n");
getch();
return 0;
}
for(i=0; i<MaxStu; i++) { //M107
sp->exist[i]=0; //初始化
sp->students[i].age=-1; //默认年龄-1,M107
sp->students[i].sex=-1; //默认性别-1,M107
strcpy(sp->students[i].id, "-1"); //默认学号为-1,M107
strcpy(sp->students[i].name,"-1"); //默认姓名为-1,M107
strcpy(sp->students[i].tel, "-1"); //默认手机号码:-1,M107
}
sp->n=0;
sp->isModify=0; //修改标记
printf("\t\t初始化成功\n\t\t");
getch();
return 1;
}
STU_PROJ init() {
int i;
STU_PROJ sp;
sp = (STU_PROJ )malloc( sizeof(struct stu_proj) ); //初始化内存
if (sp == NULL) { //M106 初始化申请不到空间的情况
printf("\t\t系统无法初始化\n");
getch();
return NULL;
}
for (i = 0; i < MaxStu; i++) { //M107 初始化数据
sp->exist[i] = 0;
sp->students[i].age = -1;
sp->students[i].id[0] = -1;
sp->students[i].name[0] = -1;
sp->students[i].sex = -1;
sp->students[i].tel[0] = -1;
}
sp->n = 0;
sp->isModify=0; //M134
return sp;
}