C语言开发项目实战: C语言是一门通用计算机编程语言,广泛应用于底层开发。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的C语言程序可在许多平台正常编译运行。 C语言是一种面向过程的语言,它的先天特性决定了它并不适合写出美观的GUI界面,而在这个地方笔者选择使用C语言来实现用户登录的设计只是为了让大家感受C语言项目实战开发的过程。所以,后续描述不会像在公司当中实际项目开发文档描述一样官方、精确。 一.项目需求: 1.用户控制台; 2.功能需求,能够进行用户账号密码的注册存储、比对; 二.项目设计: 根据需求我们可以知道: 1.界面布局应当有账号密码的输入,这意味着我们在代码当中需要用户、密码标识,这个我们可以使用标准C库提供的printf函数在终端打印;同时需求用户、密码的输入的接口,这个我们可以使用标准C库提供的scanf或者gets函数去实现;同理,登录、注册、退出选项也可以直接使用上述函数实现,具体布局情况,可由个人而定。 2.根据功能需求,针对用户数据的比对我们最好采用现有的成熟的数据库去实现,但这个地方我们只讲C语言的实际应用,所以,我们可以采用C语言已有的一些数据类型去实现这样的功能。当然这也会限制我们这个程序的性能。我们可以发现:用户和密码,这两者之间的关系是应该是一一对应的,所以我们可以采用结构体的形式,实现用户和其对应密码的“捆绑”。而我们用户又不应该只有一个,所以可以采用结构体数组的形式,实现用户数据的存储。(这样的设计会有一个无法避免的问题,当程序结束,内存被释放,结构体数组内部所有数据消失。如果你还学了文件IO,我想你已经可以解决这样的问题了。) 3.用户登录时,数据的比对目前我们可以通过遍历比对,实现登录功能。而未来当问题规模庞大之后,还是应当使用数据库去管理相关数据,实现最优。 三.项目编码: 1.我们可以采用比较专业的做法,将文件进行分割成多个源文件的形式,这个比较基础,方便后续展示,笔者决定采用最“LOW”的方式,简单粗暴的把所有东西放在一个文件中; 2.具体代码实现: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> typedef struct data{ char name[20]; //存储用户名 char pass[20]; //存储密码 }user_data; user_data user[20] = {0}; //能够保存20个用户的结构体数组 int last = 0; //标志位,标记已经注册账户的数目 bool reg_string(void) { int i = 0, n; if(last >= 20){ return false; } char name[20] = {0}, pass[20] = {0}; printf("please input your usrname:\n"); xxx: scanf("%s", name); getchar(); //读取脏字符 for(i = 0; i < last; i++){ n = strcmp(name, user[i].name); if(0 == n){ printf("该用户已注册\n"); goto xxx; //若用户名相同,则跳转重新输入 } } printf("please input your usrpassword:\n"); scanf("%s", pass); strcpy(user[last].name, name); strcpy(user[last].pass, pass); last++; printf("注册成功\n"); return true; } bool log_string(void) { if(0 == last){ return false; } int i, n, m; char name[20] = {0}, pass[20] = {0}; printf("please input your usrname:\n"); scanf("%s", name); getchar(); printf("please input your usrpassword:\n"); scanf("%s", pass); getchar(); for(i = 0; i < last; i++){ //strcmp 函数返回值为"0"则表示两字符串相同 n = strcmp(user[i].name, name); m = strcmp(user[i].pass, pass); if(n == 0 && m == 0){ //未来可以提供其它接口,实现各种自定义功能 printf("登录成功!\n"); return true; } } //当程序执行到这一步,意味着结构体数组遍历完毕,未找到匹配的用户和 //密码 printf("用户或密码错误\n"); return false; } int main() { int n; while(1){ //实现界面布局 printf("***************************************\n"); printf("*****1.注册*****2.登录*****3.退出*****\n"); printf("***************************************\n"); xxx: scanf("%d", &n); getchar(); switch(n){ case 1: //应该在调用时做好返回值的判断,看对应函数是否正确调用 reg_string(); break; case 2: log_string(); //登录 break; case 3: return 0; default: goto xxx; } } } |
|