c
彩票管理系统
1、功能介绍
三种身份:普通用户,公证员,管理员。
- 普通用户:注册,登录,充值,购买彩票等等操作。
- 注册:输入账号,查重,输入密码。这些信息保存在链表中,并写入到本地文件。
- 登录: 输入账号,密码,密码需要用“*”遮挡。需要虚入验证码。
- 查看个人信息:在登录之后,来到二级页面。用户可以查看自己的信息(编号,用户名,密码,余额)。
- 修改密码: 新密码与旧密码不能一致,否则提示修改错误。
- 账户充值: 输入需要充值的金额,并确定。
- 购买彩票: 期提是有正在发行的彩票,否则无法购买;彩票由管理员发行。用户可以随机生成彩票号码,也可以手填。
- 查看历史记录: 用户可以自己过往的购买记录。从彩票链表中找到自己购买的节点。
- 公证员:
- 账号和密码固定为:notery
- 登录时需要隐藏密码,并要求输入验证码。
- 开奖:登陆之后,(前提是已有正在发行的彩票)进行开奖。并确定。随机产生几个数字作为中奖号码。
- 开奖结束之后,公证员可以决定是否立即发放奖金。
- 公证员在闲暇之余,可以玩游戏。目前只完成了“剪刀石头布”。还有“贪吃蛇”和"坦克大战"有待开发。
- 管理员:
- 可以查看所有用户的信息。
- 可以查询单个用户的信息。
- 发行彩票,彩票期号根据日期时间自动生成。需要由管理员设置彩票单价。
- 可以对用户链表进行排序(根据姓名或者ID),并保存。
- 奖金发放。在当前正在发行的彩票期号下,确定有用户购买,并由公证员开奖。根据用户彩票号码,将奖金从奖池中取出发放给中奖用户。
- 手动向奖池中添加金额。
- 删除用户。可以由管理员进行,将某用户进行删除。
- 查看全部购买信息。从彩票链表中,显示出所有彩票信息。
交互界面涉及:
本工程采用的是MVC架构设计,即模块,界面,以及控制。
在src/lotview.c中,通过system(“clear”); 和printf();不断的刷屏,达到一种动态的交互效果。
在src/lotcontrol.c中,各个界面的控制逻辑,通过switch,case来构成。
其中比较核心的一个函数是:choose=key_udrl(choose,4,3);该函数是交互动态效果的核心。通过键盘按键的上下左右以及数字,修改choose值,进入相应的逻辑。并且在lotview.c中动态的刷新。
技术难点:
- 未使用数据库,而是采用创建链表,并保存到本地文件的形式。
- 链表使用过程中,涉及到动态内存的申请与释放。
- 人生中第一次开始意识到段错误的可怕,以及预防段错误的好习惯。
2、代码
工程代码下载地址:https://github.com/Kshine2017/My_GCC/tree/master/lottery_Kshine201708
工程目录如下:
root@kshine-virtual-machine:/home/kshine/桌面/lottery_Kshine201708# tree
.
├── bin
│ └── main
├── common.bin
├── include
│ ├── freelink.h
│ ├── fun.h
│ ├── gamejsb.h
│ ├── loadsave.h
│ ├── lotcontrol.h
│ ├── lottery.h
│ ├── lotview.h
│ ├── pic.h
│ └── udrl.h
├── iss.bin
├── makefile
├── obj
│ ├── freelink.o
│ ├── fun.o
│ ├── gamejsd.o
│ ├── loadsave.o
│ ├── lotcontrol.o
│ ├── lottery.o
│ ├── lotview.o
│ ├── main.o
│ ├── pic.o
│ └── udrl.o
├── src
│ ├── freelink.c
│ ├── fun.c
│ ├── gamejsd.c
│ ├── loadsave.c
│ ├── lotcontrol.c
│ ├── lottery.c
│ ├── lotview.c
│ ├── main.c
│ ├── pic.c
│ ├── udrl.c
│ └── 锛_
├── tic.bin
└── user.bin
拎出几个文件或者函数,做简单的展示分析:
- udrl.c (up down right left)
#include <stdio.h>
#include <stdlib.h>
#include "lotview.h"
int key_udrl(int choose,int menu_num,int mode)
{
printf("\n\033[47;31m\t\t\t敲击Enter继续!\033[0m\n");
getchar();
while (1)
{
char c =0;
if(mode==1)
{
V_main_menu_move(choose);
}
else if(mode==2)
{
V_game_move(choose);
}
else if(mode==3)
{
V_other_move(choose);
}
else if(mode==4)
{
V_sort_move(choose);
}
else if(mode==5)
{
V_admin_menu_move(choose);
}
else if(mode==6)
{
V_user_menu_move(choose);
}
else if(mode==7)
{
V_notery_menu_move(choose);
}
while(1) //自动清掉奇怪的符号
{
system("stty -icanon");//关闭缓冲区,输入字符无需回车直接接受
c=getchar();
if(c=='\n')
{
return choose;
}
if((c>='a'&&c<='z')&& (c>='A'&&c<='Z') && (c>='9'&&c<='0'))
{
printf("\b");
continue;
}
else //是字母或者数字
{
break;
}
}
//得到上下左右或者字母数字
if(c<='9'&&c>='0')//返回数值,直接控制
{
choose = (int)(c-'0');//不要急着返回
}
else
{
if(c=='A')//up
{
choose--;
}
if(c=='B')//down
{
choose++;
}
if(c=='D')//left
{
choose=0;
}
if(c=='C')//right
{
//进入当前的choose菜单
break;
}
}
//--------------------
if(choose<0)
{
choose += menu_num;
}
if(choose>menu_num-1)
{
choose -=(menu_num);
}
//-----动态显示
//V_main_menu_move(choose);
//----
}
return choose;
}
在fun.c文件中
- //遮挡输入的数值
char* secret_num(char* str)
{
char ch=0;
int i=0;
getchar();
while(1)
{
system("stty -icanon");//关闭缓冲区,输入字符无需回车直接接受
ch=getchar();
printf("\b@");
if(ch=='\n')
{
break;
}
str[i++]=ch;
}
str[i]='\0';
return str;
}
- //验证码
int identifying_code()
{
char array[100]={"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"};
char a[5]="";
char b[5]="";
srand(time(NULL));
a[0]=array[rand()%62];
a[1]=array[rand()%62];
a[2]=array[rand()%62];
a[3]=array[rand()%62];
printf("验证码是:");
printf("\033[42;31m%s\033[0m\n",a);
printf("请输入您的验证码:");
scanf("%s",b);
if(strcmp(a,b)==0)
{
printf("验证成功!\n");
return 0;
}
else
{
printf("验证失败!");
return 1;
}
return 0;
}
3、编译运行
项目中写了makefile文件,用户可以直接输入make或者make clean。
CC:=gcc
DEPEND:=obj/main.o
DEPEND+=obj/lotcontrol.o
DEPEND+=obj/fun.o
DEPEND+=obj/udrl.o
DEPEND+=obj/lotview.o
DEPEND+=obj/loadsave.o
DEPEND+=obj/freelink.o
DEPEND+=obj/pic.o
DEPEND+=obj/lottery.o
DEPEND+=obj/gamejsd.o
bin/main:$(DEPEND)
$(CC) $^ -o $@
obj/%.o:src/%.c
$(CC) -c $^ -o $@ -Iinclude
clean:
rm -rf obj/$(DEPEND)
rm -rf src/*.c~
4、运行展示
欢迎界面:
主界面:
用户登录:
用户界面
用户-查看历史记录
公证员界面:
管理员界面:
管理员-用户排序:
其他信息界面:
其中基本信息为文字信息。图标为开机的画面。二维码,是我无聊,将某机构的网址转成的二维码图片。(用户可以根据自己的需求,自己讲图片转成数组,再替换到这里)。由于终端通过单个字符来表示一个像素点,且为了使图样不走形,导致图像很大。这也是终端显示的缺点之一。还是把显示出来的二维码,展示一下吧。
还有一些功能,需要你自己去发现和完善。