/* 1.操作式、功能宏和常量宏必须使用括号
2.指针使用NULL判断; 释放后显式赋值为NULL
3.memcpy、memcmp均使用memncpy、memncmp,防止内存越界;memncpy可以使用源长度*/
#include<stdio.h> /*I/O函数*/
#include<stdlib.h> /*其它说明*/
#include<string.h> /*字符串函数*/
#define LEN 15 // 学号、姓名、班级、性别、文件名最大字符数,实际请更改
#define N 1000 /* 最大学生人数,实际请更改*/
int student_number = 0; //student_number代表当前记录的学生人数
int circulate=1; //主函数循环标志
//函数声明
void seek(); //查找学生信息
void insert(); //添加学生信息函数
void import(); //导入学生文本信息
void display(); //显示当前学生信息
void menu(); //菜单选择
struct student{
char Id[LEN+1]; //scanf()时末尾自动加上'\0'
char Name[LEN+1];
int Age;
char Sex[LEN+1];
char Address[LEN+1];
char Class[LEN+1];
}stu[N];
void fun(char* str) //防止输入字符串越界
{
for (int i = 0, ch = '\0'; ch != '\n'; i++)
{
ch = getchar();
if (i >= LEN+1)
{//当超出字符串长度时, 继续接受键盘输入的字符,直到输入\n为止
//这是为了防止字符串输入完成后输入的字符会被下一个需要输入的数据接收
continue;
}
if (ch == '\n' || i == N - 1) {
str[i] = '\0';
continue;
}
str[i] = ch;
}
}
//主函数
int main()
{
while (circulate)
{
fflush(stdin);//清理缓冲区,防止在switch语句中输入字符出现死循环。。fflush(stdin)刷新标准输入缓冲区,fflush(stdout)刷新标准输出缓冲区
menu(); //最新版的VS2019可能无法使用fflush(stdin)函数消除缓冲区,可以使用rewind(stdin)函数替换,效果相同。
}
system("pause"); //暂停程序的执行,等待任意键继续执行
return 0;
}
// 界面
void menu()
{
int num; //菜单编号
printf(" 请选择以下编号:\n");
printf("0.查找学生信息\n");
printf("1.添加学生信息\n");
printf("2.导入学生信息\n");
printf("3.显示当前已添加的学生信息\n");
printf("4.退出系统\n");
scanf("%d", &num);
switch (num)
{
case 0:
seek();
break;
case 1:
insert();
break;
case 2:
import();
break;
case 3:
display();
break;
case 4:
circulate = 0; //跳出主函数循环
//printf("即将退出程序!\n");
break;
default:
printf("请在0-4之间选择\n");
}
}
//添加学生信息函数
void insert()
{
int i = student_number;
int j;
int flag;
int increase_number;
int increase_most;
printf("请输入待增加的学生数:\n");
scanf("%d", &increase_number);
if(increase_number <= 0)
{
printf("请输入大于0的数字\n");
}
else if((student_number+increase_number)>N)
{
printf("增加的人数超过限制\n");
increase_most = N-student_number;
printf("最多还可添加%d人\n",increase_most);
}
else
{
while (i<(student_number + increase_number))
{
flag = 1;
while (flag)
{
flag = 0;
//fflush(stdin);
printf("请输入第%d位学生的学号:\n", i + 1);
//fun(stu[i].Id);
fgets(stu[i].Id, LEN, stdin);
//scanf("%s", stu[i].Id);
//scanf_s("%s",stu[i].Id,3);
for (j = 0; j < i; j++)
{
if (strcmp(stu[j].Id, stu[i].Id) == 0) //若已经有了1800800410,刚好是数组的最大长度,输入180080041000会怎样
{
printf("该学号已存在,请重新输入!\n");
flag = 1;
break;
}
}
}
printf("请输入第%d 个学生的姓名:\n", i+1);
//scanf_s("%s",stu[i].Name,3);
//fun(stu[i].Name);
//fflush(stdin);
//fgets(stu[i].Name, LEN, stdin);
scanf("%s", stu[i].Name);
printf("请输入第%d 个学生的年龄:\n", i+1);
//fgets(stu[i].Name, LEN, stdin);
scanf("%d", &stu[i].Age);
//fflush(stdin);
printf("请输入第%d 个学生的性别:\n", i+1);
//scanf_s("%s",stu[i].Sex,3);
//fun(stu[i].Sex);
//fflush(stdin);
//fgets(stu[i].Sex, LEN, stdin);
scanf(" %s", stu[i].Sex);
printf("请输入第%d 个学生的家庭地址\n",i+1);
//scanf_s("%s",stu[i].Address,3);
//fun(stu[i].Address);
//fflush(stdin);
//fgets(stu[i].Address, LEN, stdin);
scanf("%s", stu[i].Address);
printf("请输入第%d 个学生的班级信息:\n", i+1);
//scanf_s("%s",stu[i].Class,3);
//fun(stu[i].Class);
//fflush(stdin);
//fgets(stu[i].Class, LEN, stdin);
scanf("%s", stu[i].Class);
if (flag == 0)
{
i++;
}
}
student_number = student_number + increase_number;
printf("学生信息添加完毕!!!\n");
}
}
//查找学生信息
void seek()
{
int i;
int flag;
int item; //子菜单编号
char ID[21]; // 学号
char Name[21]; //姓名
int age; //查询的具体年龄
int age_low; //年龄区间查找的下限
int age_high; //年龄区间查找的上限
int age_student=0; //按年龄查询的人数
int age_section_student=0; //按年龄区间查询的人数
printf("请选择子菜单编号:\n");
printf("1.按学号查询\n");
printf("2.按姓名查询\n");
printf("3.按年龄查询\n");
printf("4.年龄区间查询\n");
printf("5.退出本菜单\n");
while (1)
{
printf("请选择子菜单编号:");
scanf("%d", &item);
flag = 0;
switch (item)
{
case 1:
printf("请输入要查询的学生的学号:\n");
scanf("%s", ID);
for (i = 0; i<student_number; i++)
{
if (strcmp(stu[i].Id,ID) == 0) //????哪个为主体 strcmp怎么防止越界
{
flag = 1;
printf("学生学号\t学生姓名\t年龄\t性别\t家庭地址\t班级信息\n");
//printf("--------------------------------------------------------------------\n");
printf("%s\t\t%s\t%d\t%s\t%s\t\t%s\n", stu[i].Id, stu[i].Name, stu[i].Age, stu[i].Sex, stu[i].Address, stu[i].Class);
}
}
if (flag == 0)
printf("该学号不存在!\n");
break;
case 2:
printf("请输入要查询的学生的姓名:\n");
scanf("%s", Name);
for (i = 0; i<student_number; i++)
{
if (strcmp(stu[i].Name, Name) == 0)
{
flag = 1;
printf("学生学号\t学生姓名\t年龄\t性别\t家庭地址\t班级信息\n");
//printf("--------------------------------------------------------------------\n");
printf("%s\t\t%s\t%d\t%s\t%s\t\t%s\n", stu[i].Id, stu[i].Name, stu[i].Age, stu[i].Sex, stu[i].Address, stu[i].Class);
}
}
if (flag == 0)
printf("该姓名不存在!\n");
break;
case 3:
printf("请输入要查询的学生年龄:\n");
scanf("%d", &age);
for (i = 0; i<student_number; i++)
{
if (stu[i].Age==age)
{
{
age_student++;
flag = 1;
printf("学生学号\t学生姓名\t年龄\t性别\t家庭地址\t班级信息\n");
//printf("--------------------------------------------------------------------\n");
printf("%s\t\t%s\t%d\t%s\t%s\t\t%s\n", stu[i].Id, stu[i].Name, stu[i].Age, stu[i].Sex, stu[i].Address, stu[i].Class);
}
printf("年龄为%d的学生人数为%d\n",age,age_student);
age_student=0;
}
}
if (0 == flag)
printf("不存在该年龄的学生!\n");
break;
case 4:
printf("请输入要查询的学生年龄下限:\n");
scanf("%d", &age_low);
printf("请输入要查询的学生年龄上限:\n");
scanf("%d", &age_high);
if(age_low<age_high)
{
for (i = 0; i<student_number; i++)
if (age_low<=stu[i].Age&&stu[i].Age<=age_high)
{
age_section_student++;
flag = 1;
printf("学生学号\t学生姓名\t年龄\t性别\t家庭地址\t班级信息\n");
//printf("--------------------------------------------------------------------\n");
printf("%s\t\t%s\t%d\t%s\t%s\t\t%s\n", stu[i].Id, stu[i].Name, stu[i].Age, stu[i].Sex, stu[i].Address, stu[i].Class);
}
printf("年龄在%d到%d学生人数为%d\n",age_low,age_high,age_section_student);
age_section_student=0;
}
if(age_low>=age_high)
printf("年龄上下限输入有误\n");
if (flag == 0)
printf("不存在该年龄段的学生!\n");
break;
case 5:
return;
default:
printf("请在1-5之间选择\n");
}
}
}
//导入学生信息
void import() //导入两次重复????
{
int flag=0;
int unimport=0;
int i;
int j=student_number;
char filename[LEN + 1];
int import_sucess=0;
int import_failure=0;
printf("请输入要导入学生信息的文件名:\n"); //判断是否越界
scanf("%s", filename);
FILE *file = fopen(filename,"r"); //文件名有什么要求?? 是否需要.txt文件
if(!file)
{
printf("文件名输入有误/此文件为空\n"); //前一版本代码为return
return;
}
while (fscanf(file, "%s %s %d %s %s %s ", stu[j].Id, stu[j].Name, &stu[j].Age, stu[j].Sex, stu[j].Address, stu[j].Class) == 6)
{
flag = 1;
while (flag)
{
flag = 0;
//printf("请输入第%d位学生的学号:\n", i + 1);
//scanf("%s", stu[i].Id);
for (i= 0; i<student_number; i++)
{
if (strcmp(stu[i].Id, stu[j].Id) == 0)
{
printf("该学号已存在");
import_failure++;
flag = 1;
break;
}
}
}
if (flag == 0)
{
j++;
import_sucess++;
student_number++;
if(student_number==N)
{
printf("已达最大人数");
break;
}
}
}
while (fscanf(file, "%s %s %d %s %s %s ", stu[j].Id, stu[j].Name, &stu[j].Age, stu[j].Sex, stu[j].Address, stu[j].Class) == 6)
{
unimport++;
}
printf("学生信息导入完毕!!!\n");
printf("成功导入学生信息%d条\n",import_sucess);
printf("重复学生信息%d条\n",import_failure);
printf("剩余未导入学生信息%d条\n",unimport);
fclose(file);
system("pause"); //暂停程序的执行,等待任意键继续执行
}
//显示全部数据信息
void display()
{
int i;
printf("共有%d位学生的信息:\n", student_number);
if (student_number != 0)
{
printf("学生学号\t学生姓名\t年龄\t性别\t家庭地址\t班级信息\n");
printf("--------------------------------------------------------------------\n");
for (i = 0; i<student_number; i++)
{
printf("%s\t%s\t%d\t%s\t%s\t\t%s\n", stu[i].Id, stu[i].Name, stu[i].Age, stu[i].Sex, stu[i].Address,stu[i].Class);
}
}
else
printf("当前暂无学生信息\n");
system("pause");
}
08-05
116
03-19
871