C语言实现一个Window控制台带彩色,且可以用方向键选择并确认的菜单式列表(二) ---学生信息管理系统

简介: http://blog.csdn.net/morixinguan/article/details/77485367上节,我们写了一个简单的列表框架,是关于学生信息管理系统的,这节,我们来把它尽量的完善一下。

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

上节,我们写了一个简单的列表框架,是关于学生信息管理系统的,这节,我们来把它尽量的完善一下。

目前,我这边已经除了学生信息修改以及学生信息删除还没有做好,其余功能已经可以正常使用,我们来看看程序的实现,往后更新了这两个接口,会将本文继续修改。

我们来看看代码的实现:

student_project_for_window.c

#include <stdio.h>
#include <Windows.h>
#include <conio.h>
#include <stdlib.h>
#include <unistd.h>
#define   NR(x)   (sizeof(x)/sizeof(x[0]+0))
#define  TITLE  "学生信息管理系统"
#define  AUTHOR "作者:杨源鑫"
#define  DATE   "日期:2017年8月22日"
#define  SIZE   100
//定义枚举Keyboard的键值数据 
enum 
{
	UP = 72,
	DOWN = 80 ,
	LEFT = 75 ,
	RIGHT = 77 ,
	ENTER = 13 ,
	ESC = 27 ,
};

//存储学生信息的结构体
struct student
{
	char name[20] ; //名字
	int  id ; 	    //学生ID
	float score ;   //分数
};

//学生的个数
int stucount ; 
//定义一个数组,用于存储学生信息  
struct student array[SIZE] = {0}; 

//定义要显示的菜单 
char *menu[] = 
{
	"*学生信息添加*",
	"*学生信息查找*",
	"*学生信息打印*",
	//"*学生信息修改*",
	//"*学生信息删除*",
	"*学生信息保存*",
	"*学生信息导入*",
	"*    退出    *",
};

//定义结构体
CONSOLE_CURSOR_INFO cci; 
//定义默认的坐标位置  	
COORD pos = {0,0};
//显示菜单 
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 main()
{
    int i;
    int ret ;
    int index = 0 ;
    HANDLE hOut;
    SetConsoleTitleA(TITLE);
    //获取当前的句柄---设置为标准输出句柄 
    hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    //获取光标信息
    GetConsoleCursorInfo(hOut, &cci); 
	//设置光标大小   
    cci.dwSize = 1; 
	//设置光标不可见 FALSE   
    cci.bVisible =  0; 
    //设置(应用)光标信息
    SetConsoleCursorInfo(hOut, &cci);   
    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 3:  stu_save(hOut); break ; 	//学生信息保存
				case 4:  stu_load(hOut); break ;    //学生信息导入
				case 5:  system("cls");return 0 ;   //退出学生信息管理系统
			}
		}
	}
    return 0;
}

void showmenu(HANDLE hOut ,char **menu , int size , int index)
{
	int i ; 
	system("cls");	
	//设置显示的文本的颜色 
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	//初始化控制台显示的X,Y轴的坐标 
	pos.X = 30;
	pos.Y = 0 ;
	//设置显示到控制台终端的具体位置 
	SetConsoleCursorPosition(hOut,pos);    
	//调用printf在控制台对应的位置上输出 
	printf("%s",TITLE);
	pos.X = 32;
	pos.Y = 1 ;
	SetConsoleCursorPosition(hOut,pos);    
	printf("%s",AUTHOR);
	pos.X = 30;
	pos.Y = 2 ;
	SetConsoleCursorPosition(hOut,pos);    
	printf("%s",DATE);
	for(i = 0 ; i < size ; i++)
	{
		//如果i==index表示在当前选项的位置,默认初始化显示是第一项,显示为红色,
		//当按下上下按键选择的时候,光标会移动,也就看到了列表选择的现象 
		if(i == index)
		{
			//红色 
			SetConsoleTextAttribute(hOut, FOREGROUND_RED | 0x8); 
			pos.X = 30;
    		pos.Y = 5+i;
    		//设置光标坐标
    		SetConsoleCursorPosition(hOut,pos);    
    		printf("%s",menu[i]);
		}
		//否则显示为白色 
		else
		{
			//白色 
			SetConsoleTextAttribute(hOut, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); 
			pos.X = 30;
    		pos.Y = 5+i;
    		//设置光标坐标
    		SetConsoleCursorPosition(hOut,pos);    //设置光标坐标
    		printf("%s",menu[i]);
		}
	}
	//刷新标准输出缓冲区 
	fflush(stdout);
}

//获取用户输入的接口 
int  get_userinput(int *index , int size)
{
	int ch ;
	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)
{
	system("cls");
	//设置显示的文本的颜色 
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	//初始化控制台显示的X,Y轴的坐标 
	pos.X = 15;
	pos.Y = 0 ;
	//设置显示到控制台终端的具体位置 
	SetConsoleCursorPosition(hOut,pos);   
	printf("                  学生信息添加\n");
	if(stucount >= SIZE)
		printf("学生信息已经满\n");
	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)
{
	system("cls");
	//设置显示的文本的颜色 
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	//初始化控制台显示的X,Y轴的坐标 
	pos.X = 15;
	pos.Y = 0 ;
	//设置显示到控制台终端的具体位置 
	SetConsoleCursorPosition(hOut,pos); 
	printf("                  学生信息打印\n");
	fflush(stdout);
	int i ; 
	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("分数:%f ",array[i].score);
	}
	fflush(stdout);
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 0;
	pos.Y = 20 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("Please press any key to continue ... \n");
	getchar();  //阻塞
}
//查找ID
static void search_id(HANDLE hOut,int id)
{
	system("cls");
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 15;
	pos.Y = 0 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("                  查找到学生的信息\n");
	fflush(stdout);
	int i ,j ; 
	for(i = 0 , j = 0 ; i < stucount ; i++)
	{
		if(array[i].id == id)
		{
			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++ ; 
		}
	}
	fflush(stdout);
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 0;
	pos.Y = 20 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("Please press any key to continue ... \n");
	getchar(); 
}
//查找姓名
static void search_name(HANDLE hOut,const char *name)
{
	system("cls");
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 15;
	pos.Y = 0 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("                  查找到学生的信息\n");
	fflush(stdout);
	int i , j; 
	for(i = 0 , j = 0; i < stucount ; i++)
	{
		if(strcmp(array[i].name , name) == 0)
		{
			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++ ; 
		}
	}
	fflush(stdout);

	
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 0;
	pos.Y = 20 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("Please press any key to continue ... \n");
	getchar();
}

//学生信息查找
void stu_search(HANDLE hOut)
{
	char ch ; 
	int id ; 
	char name[30] ; 
repeat:
	system("cls");
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 15;
	pos.Y = 0 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("                  学生信息查找\n");
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 20;
	pos.Y = 0 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("请选择按什么方式查找学生信息 :\n");
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 10;
	pos.Y = 1 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("			1.ID \n");
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 10;
	pos.Y = 2 ;
	SetConsoleCursorPosition(hOut,pos);
	printf("			2.NAME \n");
	fflush(stdout);
	//获取要输入的信息
	ch = getchar();  
	if(ch == '1')
	{
		system("cls");
		SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
		pos.X = 0;
		pos.Y = 1 ;
		SetConsoleCursorPosition(hOut,pos); 
		printf("请输入学生ID: ");
		fflush(stdout);
		scanf("%d" , &id);
		getchar();
		if(id < 0)
		{
			getchar();
			SetConsoleTextAttribute(hOut, FOREGROUND_RED | 0x8); 
			pos.X = 0;
			pos.Y = 20 ;
			SetConsoleCursorPosition(hOut,pos); 
			printf("请入ID有误,请按任意键重新选择输入\n");
			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:
	system("cls");
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 15;
	pos.Y = 0 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("                  学生信息保存\n");
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 20;
	pos.Y = 0 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("请选择按什么方式保存学生信息 :\n");
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 10;
	pos.Y = 1 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("			1.追加 \n");
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 10;
	pos.Y = 2 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("			2.覆盖 \n");
	fflush(stdout);
	ch = getchar();  
	system("cls");
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 0;
	pos.Y = 1 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("请输入保存文件名:\n");
	scanf("%s" , Path);
	getchar();
	if(ch == '1')
	{
		filp = fopen(Path , "a+");
		if(NULL == filp)
		{
			SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
			pos.X = 0;
			pos.Y = 20 ;
			SetConsoleCursorPosition(hOut,pos); 
			fprintf(stderr , "文件打开失败 \n");
			SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
			pos.X = 0;
			pos.Y = 21 ;
			SetConsoleCursorPosition(hOut,pos); 
			printf("请按任意键重新选择输入\n");
			getchar(); 
			goto  repeat1;
		}
	}
	if(ch == '2')
	{
		filp = fopen(Path , "w+");
		if(NULL == filp)
		{
			SetConsoleTextAttribute(hOut, FOREGROUND_RED | 0x8); 
			pos.X = 0;
			pos.Y = 20 ;
			SetConsoleCursorPosition(hOut,pos); 
			fprintf(stderr , "文件打开失败 \n");
			SetConsoleTextAttribute(hOut, FOREGROUND_RED | 0x8); 
			pos.X = 0;
			pos.Y = 21 ;
			SetConsoleCursorPosition(hOut,pos); 
			printf("请按任意键重新选择输入\n");
			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);
	printf("学生信息保存完毕\n");
	sleep(1) ; 
}
//学生信息装载
void stu_load(HANDLE hOut)
{
	FILE *filp = NULL ; 
	char Path[30] ; 
	system("cls");
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 15;
	pos.Y = 0 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("                  学生信息加载\n");
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 0;
	pos.Y = 1 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("请输入导入文件名 :\n");
	scanf("%s" , Path);
	getchar();
	int i ; 
	filp = fopen(Path , "r");
	if(NULL == filp)
	{
		SetConsoleTextAttribute(hOut, FOREGROUND_RED | 0x8); 
		pos.X = 0;
		pos.Y = 20 ;
		SetConsoleCursorPosition(hOut,pos); 
		fprintf(stderr , "文件打开失败 \n");
		SetConsoleTextAttribute(hOut, FOREGROUND_RED | 0x8); 
		pos.X = 0;
		pos.Y = 21 ;
		SetConsoleCursorPosition(hOut,pos); 
		printf("请按任意键退出 \n");
		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);
	system("cls");
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 0;
	pos.Y = 20 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("学生信息导入完毕\n");
	sleep(1);
}
//学生信息修改
void stu_modefi(HANDLE hOut)
{
	int id ; 
	system("cls");
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 15;
	pos.Y = 0 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("                  学生信息修改\n");
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 0;
	pos.Y = 1 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("ID:\n");
	fflush(stdout);
	scanf("%d" , &id);
	int i ; 
	system("cls");
	for(i = 0 ; i < stucount ; i++)
	{
		if(array[i].id == id)
		{
			SetConsoleTextAttribute(hOut, FOREGROUND_GREEN| 0x8); 
			pos.X = 0;
			pos.Y = i+1 ;
			SetConsoleCursorPosition(hOut,pos); 
			printf("ID:%2d ",array[i].id);
			printf("姓名:%s ",array[i].name);
			printf("分数:%f ",array[i].score);
			break;
		}
	}
	getchar();
}
//学生信息删除
void stu_delete(HANDLE hOut)
{
	char ch ; 
	int id ; 
	char name[30] ; 
repeat3:
	system("cls");
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 15;
	pos.Y = 0 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("                  学生信息删除\n");
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 20;
	pos.Y = 1 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("请选择按什么方式删除学生信息 :\n");
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 10;
	pos.Y = 1 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("1.ID");
	SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
	pos.X = 10;
	pos.Y = 2 ;
	SetConsoleCursorPosition(hOut,pos); 
	printf("2.NAME\n");
	fflush(stdout);
	ch = getchar(); 
	system("cls");
	int i ; 
	if(ch == '1')
	{
		SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
		pos.X = 0;
		pos.Y = 1 ;
		SetConsoleCursorPosition(hOut,pos); 
		printf("请输入ID:\n");
		scanf("%d" , &id);
		getchar();
		for(i = 0 ; i < stucount ; i++)
		{
			if(array[i].id == id)
			{
				printf("i:%d \n" , i);
				memmove(array + i , array +i + 1 , stucount-i-1);
				stucount-- ; 
				i-- ; 
			}
		}
	}
	if(ch == '2')
	{
		SetConsoleTextAttribute(hOut, FOREGROUND_GREEN | 0x8); 
		pos.X = 0;
		pos.Y = 1 ;
		SetConsoleCursorPosition(hOut,pos); 
		printf("请输入NAME:\n");
		scanf("%s" , name);
		getchar();
		for(i = 0 ; i < stucount ; i++)
		{
			if(strcmp(array[i].name , name) == 0)
			{
				memmove(array + i , array +i + 1 , stucount-i-1);
				stucount-- ; 
				i-- ; 
			}
		}
	}
	if(ch != '1' && ch != '2')
	{
		goto repeat3;
	}
	sleep(1);
}

运行结果:

学生信息添加过程演示:


学生信息查找:


学生信息打印流程:

学生信息保存流程:


学生信息导入流程:(实验这个过程,需要先关闭程序,再重新执行一遍方可以看到效果)


好了,这就是整个程序的实现,是不是觉得比许多大学的课设,关于学生信息管理系统的要高大上很多呢?哈哈,后面还有精彩内容,敬请期待!

如有兴趣,请持续关注本博客,本博客将为你带来源源不断的干货!

http://blog.csdn.net/morixinguan



目录
相关文章
|
3月前
|
缓存 监控 NoSQL
若依修改----监控相关,主要包括在线用户,数据监控,服务监控,缓存监控,缓存列表,缓存监控有助于帮我们搞清楚redis的缓存情况,数据监控的密码控制台管理用户名和密码在application-dru
若依修改----监控相关,主要包括在线用户,数据监控,服务监控,缓存监控,缓存列表,缓存监控有助于帮我们搞清楚redis的缓存情况,数据监控的密码控制台管理用户名和密码在application-dru
|
5月前
|
编译器 C语言 C++
从C语言到C++⑦(第二章_类和对象_下篇)初始化列表+explicit+static成员+友元+内部类+匿名对象(上)
从C语言到C++⑦(第二章_类和对象_下篇)初始化列表+explicit+static成员+友元+内部类+匿名对象
34 1
|
5月前
|
Java 编译器 C语言
从C语言到C++⑦(第二章_类和对象_下篇)初始化列表+explicit+static成员+友元+内部类+匿名对象(下)
从C语言到C++⑦(第二章_类和对象_下篇)初始化列表+explicit+static成员+友元+内部类+匿名对象
28 0
|
5月前
|
C语言 C++
从C语言到C++⑦(第二章_类和对象_下篇)初始化列表+explicit+static成员+友元+内部类+匿名对象(中)
从C语言到C++⑦(第二章_类和对象_下篇)初始化列表+explicit+static成员+友元+内部类+匿名对象
43 0
|
11月前
|
存储 安全 C语言
|
5月前
|
编译器 C语言
【C语言】—— 可变参数列表
【C语言】—— 可变参数列表
【C语言】—— 可变参数列表
|
5月前
|
C语言
C语言中形参列表为指针的三种不同swap函数的通俗理解
C语言中形参列表为指针的三种不同swap函数的通俗理解
48 0
|
5月前
|
C语言
详解C语言可变参数列表(stdarg头文件及其定义的宏)
详解C语言可变参数列表(stdarg头文件及其定义的宏)
84 0
|
5月前
|
Java
java实战项目超市管理系统控制台版
java实战项目超市管理系统控制台版
|
5月前
|
Java
【Java开发指南 | 第二十篇】Java流之控制台
【Java开发指南 | 第二十篇】Java流之控制台
41 2