博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C语言实现一个列表式的学生信息管理系统(完善)
阅读量:7088 次
发布时间:2019-06-28

本文共 13750 字,大约阅读时间需要 45 分钟。

http://blog.csdn.net/morixinguan/article/details/77489633

       上节,我们实现了学生信息管理系统的大多数功能,但还有两个功能没有实现,就是学生信息修改还有学生信息删除了。当然,程序中依然存在诸多的BUG,比如,scanfgetchar函数就是一对冤家,如果用了scanf,再调用getchar,就会出现所谓的输入缓冲区问题,导致程序一闪而过。然而解决这种问题的唯一方法就是使用fflush函数,对输入缓冲区,输出缓冲区,出错缓冲区进行刷新。下面是对多数明显的程序BUG进行修复,以及添加了删除和修改的功能。但可能存在一些未发觉的BUG,需要进行程序的压力测试才能得知,但如图所示的基本功能已经完全可以正常工作了。大笑大笑

         该项目实现的效果如下:

那么这里面用到了window上的那些知识点才可以做到这样的效果呢?上节博文已经给大家介绍了两个博客。当然大家也可以去搜索这本pdf教程:

叫做C/C++控制台界面编程,可以学习下,写出炫酷的控制台程序。

接下来,我们来看下代码的具体实现:

/*	Copyright (C) 2007 The Windows console C Open Source Project 	AUTHOR:  Y.X.YANG	date:	 2017年8月23日	version: 2.0	C runtime environment : Windows DevC++ And all Windows development Software*/#include 
#include
#include
#include
#include
#include
#define NR(x) (sizeof(x)/sizeof(x[0]+0))#define TITLE "学生信息管理系统"#define AUTHOR "作者:杨源鑫"#define DATE "日期:2017年8月23日 version2"#define SIZE 100//在终端上打印信息#define Print_Info_To_console(str,hOut,pos,x,y,color_type) \ SetConsoleTextAttribute(hOut, color_type); \ pos.X = x; \ pos.Y = y ; \ SetConsoleCursorPosition(hOut,pos); \ printf("%s",str); //清屏#define ClearScreen() \ system("cls"); //定义枚举Keyboard的键值数据 enum { UP = 72, DOWN = 80 , LEFT = 75 , RIGHT = 77 , ENTER = 13 , ESC = 27 ,};//存储学生信息的结构体struct student{ char name[20] ; //名字 int id ; //学生ID float score ; //分数};//定义要显示的菜单 char *menu[] = { "*学生信息添加*", "*学生信息查找*", "*学生信息打印*", "*学生信息修改*", "*学生信息删除*", "*学生信息保存*", "*学生信息导入*", "* 退出 *",};//窗口初始化void HANDLE_init(HANDLE hOut);//显示菜单 void showmenu(HANDLE hOut ,char **menu , int size , int index) ;//获取用户输入 int get_userinput(int *index , int size) ;//学生信息添加void stu_add(HANDLE hOut);//学生信息打印void stu_show(HANDLE hOut);//学生信息查找void stu_search(HANDLE hOut);//学生信息保存void stu_save(HANDLE hOut);//学生信息导入void stu_load(HANDLE hOut);//学生信息修改void stu_modefi(HANDLE hOut);//学生信息删除void stu_delete(HANDLE hOut);//学生的个数int stucount ; //定义一个数组,用于存储学生信息 struct student array[SIZE] = {0}; //定义设置光标结构体变量CONSOLE_CURSOR_INFO cci; //定义默认的坐标位置 COORD pos = {0,0};int main(){ int i; int ret ; int index = 0 ; HANDLE hOut; hOut = GetStdHandle(STD_OUTPUT_HANDLE); HANDLE_init(hOut); while(1) { showmenu(hOut , menu , NR(menu) , index); ret = get_userinput(&index , NR(menu)); if(ret == ESC) break ; if(ret == ENTER) { switch(index) { case 0: stu_add(hOut) ; break ; //学生信息添加 case 1: stu_search(hOut);break ; //学生信息查找 case 2: stu_show(hOut); break ; //学生信息打印 case 3: stu_modefi(hOut); break ; //学生信息修改 case 4: stu_delete(hOut); break ; //学生信息删除 case 5: stu_save(hOut); break ; //学生信息保存 case 6: stu_load(hOut); break ; //学生信息导入 case 7: ClearScreen();return 0 ; //退出学生信息管理系统 } } } //关闭窗口句柄 CloseHandle(hOut); return 0;}//窗口初始化void HANDLE_init(HANDLE hOut){ SetConsoleTitleA(TITLE); //获取当前的句柄---设置为标准输出句柄 //获取光标信息 GetConsoleCursorInfo(hOut, &cci); //设置光标大小 cci.dwSize = 1; //设置光标不可见 FALSE cci.bVisible = 0; //设置(应用)光标信息 SetConsoleCursorInfo(hOut, &cci); }//菜单初始化void showmenu(HANDLE hOut ,char **menu , int size , int index){ int i ; ClearScreen(); Print_Info_To_console(TITLE,hOut,pos,30,0,FOREGROUND_GREEN | 0x8); Print_Info_To_console(AUTHOR,hOut,pos,32,1,FOREGROUND_GREEN | 0x8); Print_Info_To_console(DATE,hOut,pos,25,2,FOREGROUND_GREEN | 0x8); Print_Info_To_console("请按↑↓←→按键选择,并用Enter按键确认",hOut,pos,20,20,FOREGROUND_GREEN | 0x8); for(i = 0 ; i < size ; i++) { //如果i==index表示在当前选项的位置,默认初始化显示是第一项,显示为红色, //当按下上下按键选择的时候,光标会移动,也就看到了列表选择的现象 if(i == index){ Print_Info_To_console(menu[i],hOut,pos,30,i+5,FOREGROUND_RED | 0x8); } else{ Print_Info_To_console(menu[i],hOut,pos,30,i+5,FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | 0x8); } } //刷新标准输出缓冲区 fflush(stdout);}//获取用户输入的接口 int get_userinput(int *index , int size){ int ch ; fflush(stdin); ch = getch(); switch(ch) { //上 //如果选择上,那么光标向上移动 case UP : if(*index > 0) *index -= 1 ; break; //下 //如果选择下,那么光标向下移动 case DOWN :if(*index < size -1) *index += 1 ; break; //左 case LEFT: case 97:return 0 ; //右 case RIGHT:return 0 ; //回车 case ENTER: return ENTER ; //ESC case ESC: return ESC ; } return 0 ;}//学生信息添加void stu_add(HANDLE hOut){ ClearScreen(); if(stucount >= SIZE){ Print_Info_To_console("学生信息已经满了\n",hOut,pos,30,0,FOREGROUND_RED | 0x8); } Print_Info_To_console("学生信息添加\n",hOut,pos,30,0,FOREGROUND_GREEN | 0x8); printf("学生姓名:"); scanf("%s" , array[stucount].name); printf("\n学生ID:"); scanf("%d" , &(array[stucount].id)); printf("\n学生成绩:"); scanf("%f" , &(array[stucount].score)); stucount++ ; //清掉输入缓冲区中的\n getchar(); fflush(NULL);}//学生信息打印void stu_show(HANDLE hOut){ int i ; ClearScreen(); fflush(stdin); fflush(stdout); Print_Info_To_console("学生信息打印\n",hOut,pos,30,0,FOREGROUND_GREEN | 0x8); for(i = 0 ; i < stucount ; i++) { SetConsoleTextAttribute(hOut, FOREGROUND_RED| 0x8); pos.X = 1; pos.Y = i+4 ; SetConsoleCursorPosition(hOut,pos); printf("ID:%2d ",array[i].id); printf("姓名:%s ",array[i].name); printf("分数:%4.1f ",array[i].score); } fflush(stdout); Print_Info_To_console("Please press any key to continue ... \n",hOut,pos,0,20,FOREGROUND_GREEN | 0x8); getchar(); }//查找IDstatic void search_id(HANDLE hOut,int id){ ClearScreen(); Print_Info_To_console("查找到学生的信息\n",hOut,pos,30,0,FOREGROUND_GREEN | 0x8); fflush(stdout); int i ,j ,flag = 0; for(i = 0 , j = 0 ; i < stucount ; i++) { if(array[i].id == id) { flag = 1 ; SetConsoleTextAttribute(hOut, FOREGROUND_RED| 0x8); pos.X = 1; pos.Y = j+4 ; SetConsoleCursorPosition(hOut,pos); printf("ID:%2d ",array[i].id); printf("姓名:%s ",array[i].name); printf("分数:%f ",array[i].score); j++ ; } } if(flag == 0) { Print_Info_To_console("找不到该学生的ID,请按任意按键返回主菜单!\n",hOut,pos,0,20,FOREGROUND_RED | 0x8); getchar(); } if(flag == 1) { fflush(stdout); Print_Info_To_console("Please press any key to continue ... \n",hOut,pos,0,20,FOREGROUND_GREEN | 0x8); getchar(); }}//查找姓名static void search_name(HANDLE hOut,const char *name){ ClearScreen(); Print_Info_To_console("查找到学生的信息\n",hOut,pos,30,0,FOREGROUND_GREEN | 0x8); fflush(stdout); int i , j , flag = 0; for(i = 0 , j = 0; i < stucount ; i++) { if(strcmp(array[i].name , name) == 0) { flag = 1 ; SetConsoleTextAttribute(hOut, FOREGROUND_RED| 0x8); pos.X = 1; pos.Y = j+4 ; SetConsoleCursorPosition(hOut,pos); printf("ID:%2d ",array[i].id); printf("姓名:%s ",array[i].name); printf("分数:%f ",array[i].score); j++ ; } } if(flag == 0) { Print_Info_To_console("找不到该学生的姓名,请按任意按键返回主菜单!\n",hOut,pos,0,20,FOREGROUND_RED | 0x8); getchar(); } if(flag == 1) { fflush(stdout); Print_Info_To_console("Please press any key to continue ... \n",hOut,pos,0,20,FOREGROUND_GREEN | 0x8); getchar(); }}//学生信息查找void stu_search(HANDLE hOut){ char ch ; int id ; char name[30] ; repeat: ClearScreen(); Print_Info_To_console("学生信息查找\n",hOut,pos,30,0,FOREGROUND_GREEN | 0x8); Print_Info_To_console("请选择按什么方式查找学生信息 :\n",hOut,pos,20,0,FOREGROUND_GREEN | 0x8); Print_Info_To_console(" 1.ID \n",hOut,pos,10,1,FOREGROUND_GREEN | 0x8); Print_Info_To_console(" 2.NAME \n",hOut,pos,10,2,FOREGROUND_GREEN | 0x8); fflush(stdout); //获取要输入的信息 ch = getch(); if(ch == '1') { ClearScreen(); Print_Info_To_console("请输入学生ID: ",hOut,pos,0,1,FOREGROUND_GREEN | 0x8); fflush(stdout); scanf("%d" , &id); getchar(); if(id < 0) { getchar(); Print_Info_To_console("请入ID有误,请按任意键重新选择输入\n",hOut,pos,0,20,FOREGROUND_RED | 0x8); getchar(); goto repeat; } search_id(hOut,id); } if(ch == '2') { printf("请输入学生NAME: "); fflush(stdout); scanf("%s" , name); getchar(); search_name(hOut,name); } if(ch != '1' && ch != '2') { goto repeat; }}//学生信息保存void stu_save(HANDLE hOut){ FILE *filp = NULL ; char ch ; char Path[30] ; repeat1: ClearScreen(); Print_Info_To_console("学生信息保存\n",hOut,pos,30,0,FOREGROUND_GREEN | 0x8); Print_Info_To_console("请选择按什么方式保存学生信息 :\n",hOut,pos,20,0,FOREGROUND_GREEN | 0x8); Print_Info_To_console(" 1.追加 \n",hOut,pos,10,1,FOREGROUND_GREEN | 0x8); Print_Info_To_console(" 2.覆盖 \n",hOut,pos,10,2,FOREGROUND_GREEN | 0x8); fflush(stdout); ch = getch(); ClearScreen(); Print_Info_To_console("请输入保存文件名:\n",hOut,pos,0,1,FOREGROUND_GREEN | 0x8); scanf("%s" , Path); getchar(); if(ch == '1') { filp = fopen(Path , "a+"); if(NULL == filp) { Print_Info_To_console("文件打开失败 \n",hOut,pos,0,20,FOREGROUND_RED | 0x8); Print_Info_To_console("请按任意键重新选择输入 \n",hOut,pos,0,21,FOREGROUND_RED | 0x8); getchar(); goto repeat1; } } if(ch == '2') { filp = fopen(Path , "w+"); if(NULL == filp) { Print_Info_To_console("文件打开失败 \n",hOut,pos,0,20,FOREGROUND_RED | 0x8); SetConsoleTextAttribute(hOut, FOREGROUND_RED | 0x8); Print_Info_To_console("请按任意键重新选择输入 \n",hOut,pos,0,21,FOREGROUND_RED | 0x8); getchar(); goto repeat1; } } if(ch != '1' && ch != '2') { goto repeat1; } int i ; for(i = 0 ; i < stucount ; i++) { fwrite(&(array[i]) , sizeof(struct student) , 1 , filp); } fclose(filp); Print_Info_To_console("学生信息保存完毕\n",hOut,pos,0,20,FOREGROUND_GREEN | 0x8); sleep(1) ; }//学生信息装载void stu_load(HANDLE hOut){ int i ; FILE *filp = NULL ; char Path[30] ; ClearScreen(); Print_Info_To_console("学生信息加载\n",hOut,pos,30,0,FOREGROUND_GREEN | 0x8); Print_Info_To_console("请输入导入文件名 :\n",hOut,pos,0,1,FOREGROUND_GREEN | 0x8); scanf("%s" , Path); filp = fopen(Path , "r"); if(NULL == filp) { Print_Info_To_console("文件打开失败 \n",hOut,pos,0,20,FOREGROUND_RED | 0x8); SetConsoleTextAttribute(hOut, FOREGROUND_RED | 0x8); Print_Info_To_console("请按任意键退出 \n",hOut,pos,0,21,FOREGROUND_RED | 0x8); fflush(stdin); fflush(stdout); getchar(); return ; } char buffer[1024] ; char *p = NULL ; int ret ; while(1) { ret = fread(&(array[stucount]) , sizeof(struct student) , 1 , filp); if(ret != 1) break; stucount++ ; } fclose(filp); ClearScreen(); Print_Info_To_console("学生信息导入完毕\n",hOut,pos,0,20,FOREGROUND_GREEN | 0x8); sleep(1);}//学生信息修改void stu_modefi(HANDLE hOut){ int id ; int flag = 0 ; int location ; char ch ; replay: ClearScreen(); Print_Info_To_console(" 学生信息修改\n",hOut,pos,30,0,FOREGROUND_GREEN | 0x8); Print_Info_To_console("请输入学生ID: ",hOut,pos,0,1,FOREGROUND_GREEN | 0x8); fflush(stdout); scanf("%d" , &id); int i ; for(i = 0 ; i < stucount ; i++) { //如果ID匹配,也就是查找到这个学生的信息了 if(array[i].id == id) { flag = 1 ; //保存当前数组的位置 location = i ; break ; } } //判断是否匹配成功的标志 if(flag == 1){ flag = 0 ; //打印该学生的信息 ClearScreen(); Print_Info_To_console("找到该学生的信息如下:\n",hOut,pos,15,0,FOREGROUND_GREEN | 0x8); SetConsoleTextAttribute(hOut, FOREGROUND_GREEN| 0x8); pos.X = 0; pos.Y = 1 ; SetConsoleCursorPosition(hOut,pos); printf("ID:%2d ",array[i].id); SetConsoleTextAttribute(hOut, FOREGROUND_GREEN| 0x8); pos.X = 0; pos.Y = 2 ; SetConsoleCursorPosition(hOut,pos); printf("姓名:%s ",array[i].name); SetConsoleTextAttribute(hOut, FOREGROUND_GREEN| 0x8); pos.X = 0; pos.Y = 3 ; SetConsoleCursorPosition(hOut,pos); printf("分数:%f ",array[i].score); } else { Print_Info_To_console("请入ID有误,请按任意键重新选择输入\n",hOut,pos,0,1,FOREGROUND_RED | 0x8); fflush(stdin); getchar(); goto replay ; } //询问是否需要修改 Print_Info_To_console("请问是否需要修改该学生的信息?按1确定,按2退回到主菜单\n",hOut,pos,0,4,FOREGROUND_GREEN | 0x8); //刷新输出缓冲区 fflush(stdout); //刷新输入缓冲区 fflush(stdin); ch = getch(); ClearScreen(); if(ch == '1') { //是否需要修改学生的ID? Print_Info_To_console("是否需要修改学生的ID?按1确定,按2不需要\n",hOut,pos,0,1,FOREGROUND_GREEN | 0x8); fflush(stdout); fflush(stdin); ch = getch(); if(ch == '1') { ClearScreen(); Print_Info_To_console("修改学生ID为:",hOut,pos,0,1,FOREGROUND_GREEN | 0x8); scanf("%d" , &(array[location].id)); Print_Info_To_console("修改学生ID成功,请按任意键返回主菜单\n",hOut,pos,0,2,FOREGROUND_GREEN | 0x8); sleep(2); fflush(stdin); getchar(); return ; } if(ch == '2') { //是否需要修改学生的姓名 ClearScreen(); Print_Info_To_console("是否需要修改学生的姓名?按1确定,按2不需要\n",hOut,pos,0,1,FOREGROUND_GREEN | 0x8); fflush(stdout); fflush(stdin); ch = getch(); if(ch == '1') { ClearScreen(); Print_Info_To_console("修改学生姓名为:",hOut,pos,0,1,FOREGROUND_GREEN | 0x8); scanf("%s" , array[location].name); Print_Info_To_console("修改学生姓名成功,请按任意键返回主菜单\n",hOut,pos,0,2,FOREGROUND_GREEN | 0x8); sleep(1); fflush(stdin); getchar(); return ; } if(ch == '2') { //是否需要修改学生的成绩 ClearScreen(); Print_Info_To_console("是否需要修改学生的成绩?按1确定,按2不需要\n",hOut,pos,0,1,FOREGROUND_GREEN | 0x8); fflush(stdout); fflush(stdin); ch = getch(); if(ch == '1') { ClearScreen(); Print_Info_To_console("修改学生成绩为:",hOut,pos,0,1,FOREGROUND_GREEN | 0x8); scanf("%f" , &(array[location].score)); Print_Info_To_console("修改学生成绩成功,请按任意键返回主菜单\n",hOut,pos,0,2,FOREGROUND_GREEN | 0x8); sleep(1); fflush(stdin); getchar(); return ; } if(ch == '2') { return ; } } } } if(ch == '2') { Print_Info_To_console("请按任意键返回主菜单\n",hOut,pos,0,2,FOREGROUND_GREEN | 0x8); fflush(stdin); getchar(); return ; }}//学生信息删除void stu_delete(HANDLE hOut){ char ch ; int id ; char name[30] ; repeat3: ClearScreen(); Print_Info_To_console(" 学生信息删除\n",hOut,pos,30,0,FOREGROUND_GREEN | 0x8); Print_Info_To_console(" 请选择按什么方式删除学生信息 :\n",hOut,pos,20,0,FOREGROUND_GREEN | 0x8); Print_Info_To_console(" 1.ID",hOut,pos,10,1,FOREGROUND_GREEN | 0x8); Print_Info_To_console(" 2.NAME\n",hOut,pos,10,2,FOREGROUND_GREEN | 0x8); fflush(stdout); ch = getch(); ClearScreen(); int i , j ; if(ch == '1') { Print_Info_To_console("请输入ID:\n",hOut,pos,0,1,FOREGROUND_GREEN | 0x8); scanf("%d" , &id); getchar(); for(i = 0 ; i < stucount ; i++) { if(array[i].id == id) { SetConsoleTextAttribute(hOut, FOREGROUND_RED| 0x8); printf("删除 : ID:%d NAME:%s score:%f\n" , array[i].id , array[i].name , array[i].score); for(j = i ; j < stucount -1 ; j++) array[j] = array[j+1] ; stucount-- ; break ; } } } if(ch == '2') { Print_Info_To_console("请输入NAME:\n",hOut,pos,0,1,FOREGROUND_GREEN | 0x8); scanf("%s" , name); getchar(); for(i = 0 ; i < stucount ; i++) { if(strcmp(array[i].name , name) == 0) { SetConsoleTextAttribute(hOut, FOREGROUND_RED| 0x8); printf("删除 : ID:%d NAME:%s score:%f\n" , array[i].id , array[i].name , array[i].score); for(j = i ; j < stucount -1 ; j++) array[j] = array[j+1] ; stucount-- ; break ; } } } if(ch != '1' && ch != '2') { goto repeat3; } sleep(1);}
重点看下最新的两个接口的更新演示过程:

学生信息修改演示:

学生信息删除演示:

    

你可能感兴趣的文章
unity, 使导入的材质名与3dmax中一致
查看>>
SpringMVC简单例子
查看>>
蓝牙音箱连接成功但没有声音还是电脑的声音
查看>>
ng-file-upload结合springMVC使用
查看>>
005 Hadoop的三种模式区别
查看>>
在笛卡尔坐标系上描绘函数 y=4x^2-2/4x-3
查看>>
ubuntu 下无损扩展分区
查看>>
Caused by: org.xml.sax.SAXParseException; lineNumber: 1
查看>>
手机资源共享
查看>>
Mahout-DistanceMeasure (数据点间的距离计算方法)
查看>>
在线研讨会网络视频讲座 - 方案设计利器Autodesk Infrastructure Modeler 2013
查看>>
【转】批量杀进程
查看>>
通过file_get_contents执行带参数的php
查看>>
Java 公历转农历,然后农历减一年(或者几天或者任意天),再把这个日期转成公历...
查看>>
Hibernate HQL查询:
查看>>
系统吞吐量(TPS)、用户并发量、性能测试概念和公式
查看>>
R语言笔记1--向量、数组、矩阵、数据框、列表
查看>>
大数进制转换 poj1220
查看>>
练习--LINUX进程间通信之有名管理FIFO
查看>>
使用memcached加速web应用实例
查看>>