1.导言
学习动态内存管理、与缓冲相关的知识,以及文件管理之后,我便制作了这个简易版的学生管理系统。其中缓冲部分你可能觉得多余(我也这么认为),但为了巩固缓冲的知识我还是加了上去。因此带来的阅读不便,还请见谅!最后希望各位客官指正错误,提出建议。
2.正文
1.菜单打印
void menu(void) //打印菜单
{
printf("\t\t\t录入学生信息(w)\n");
printf("\t\t\t删除学生信息(d)\n");
printf("\t\t\t打印学生信息(p)\n");
}
2.定义宏
#define DATA_TYPE "%d %s %d" //定义格式化输入
#define DATA_TYPE_P "\t\t\t%-24d%-24s%-28d\n" //定义格式化输出
#define DATA_P stu->id, stu->name, stu->age //定义打印数据
#define DATA &stu->id, stu->name, &stu->age //定义获取数据
#define DATA_C &stu[count].id, stu[count].name, &stu[count].age //定义获取数据,组成数组
#define DATA_P_C stu[i].id, stu[i].name, stu[i].age //定义打印数据,数组输出
3.定义学生信息的结构体
typedef struct student_library // 定义学生信息的结构体
{
int id;
char name[50];
int age;
}STULIB;
4.声明自定义函数 (函数功能详见下文)
void my_fwrite(const char* filename);
void my_printf(const char* filename);
void my_delete(const char* filename, int stu_id);
5.定义缓冲区
char buffer[BUFSIZ]; //设置缓冲区大小
setvbuf(stdout, buffer, _IOFBF, BUFSIZ); //设置缓冲区,大小512个字节
6.定义文件地址
const char* filename = "C:\\Users\\fusheng\\Desktop\\stu_sys.txt"; //获取文件地址
7.录入学生信息
void my_fwrite(const char* filename)
{
FILE* fp = NULL;
fp = fopen(filename, "a");
if (fp == NULL) //如果打开文件失败,退出程序
{
perror("\t\t\terror: ");
return;
}
STULIB* stu = NULL;
stu = (STULIB*)calloc(1, sizeof(STULIB)); //如果内存开辟失败退出程序
if (stu == NULL)
{
perror("\t\t\terror: ");
fclose(fp);
return;
}
printf("\t\t\t请输入学生id"); //打印提示信息
printf("\t\t\t请输入学生姓名");
printf("\t\t\t请输入学生年龄\n\t\t\t");
fflush(stdout); //刷新缓冲区
scanf(DATA_TYPE, DATA); //获取信息填入结构体指针变量stu所指向的空间中
fprintf(fp, DATA_TYPE_P, DATA_P); //录入学生信息到stu_sys文件中
printf("\t\t\t学生信息已录入!\n");
fflush(stdout);
fclose(fp);
free(stu); //释放空间
Sleep(2000);
}
8.删除学生信息
void my_delete(const char* filename, int stu_id)
{
FILE* fp = NULL;
fp = fopen(filename, "r");
if (fp == NULL)
{
perror("\t\t\terror: ");
return;
}
STULIB* stu = NULL;
stu = (STULIB*)calloc(100, sizeof(STULIB));
if (stu == NULL)
{
perror("\t\t\terror: ");
fclose(fp);
return;
}
int count = 0;
while (fscanf(fp, DATA_TYPE, DATA_C) != EOF ) //统计系统中存储的学生人数
{
++count;
}
fclose(fp);
fp = fopen(filename, "w");
if (fp == NULL)
{
perror("\t\t\terror: ");
return;
}
int i = 0;
int j = 0;
for (i = 0; i < count; ++i)
{
if (stu_id != stu[i].id) //将不需要删除信息的其他学生信息重新填入
{
fprintf(fp, DATA_TYPE_P, DATA_P_C);
++j;
}
}
if (j == count)
{
printf("\t\t\t学生信息不存在!\n");
}
else
{
printf("\t\t\t学生信息已删除!\n");
}
fflush(stdout);
fclose(fp);
free(stu);
Sleep(2000);
}
9.显示学生信息
void my_printf(const char* filename)
{
FILE* fp = NULL;
fp = fopen(filename, "r");
if (fp == NULL)
{
perror("\t\t\terror: ");
return;
}
STULIB* stu = NULL;
stu = (STULIB*)calloc(1, sizeof(STULIB));
if (stu == NULL)
{
perror("\t\t\terror: ");
fclose(fp);
return;
}
printf("\t\t\t学生ID\t\t\t学生姓名\t\t学生年龄\n");
while (fscanf(fp, DATA_TYPE, DATA) != EOF)
{
printf(DATA_TYPE_P, DATA_P);
}
printf("\t\t\t是否退出浏览(Y/N)\n");
fflush(stdout);
while (1)
{
if (getchar() == 'Y')
{
fclose(fp);
return;
}
}
}
10.主函数
int main(void)
{
setvbuf(stdout, buffer, _IOFBF, BUFSIZ); //设置缓冲区,大小512个字节
const char* filename = "C:\\Users\\fusheng\\Desktop\\stu_sys.txt"; //获取文件地址
//menu();
//printf("\t\t\t请输入: \n\t\t\t");
int temp;
while (1)
{
//system("cls");
menu();
printf("\t\t\t请输入: \n\t\t\t");
fflush(stdout); //刷新缓冲区
again: switch (getchar()) //获取要实现的功能
{
case 'w':
system("cls");
my_fwrite(filename); //录入学生信息
system("cls");
break;
case 'd':
system("cls");
int stu_id;
printf("\t\t\t请输入要删除学生的学号\n\t\t\t");
fflush(stdout);
scanf("%d", &stu_id);
my_delete(filename, stu_id); //删除学生信息
system("cls");
break;
case 'p':
system("cls");
my_printf(filename); //查看学生信息
system("cls");
break;
case 10 : //使用goto语句不断利用getchar清空缓冲区
goto again;
break;
default:
break;
}
}
return 0;
}