多文件编程练习
多文件编程是完成大型项目的必经之路。这里用之前写过的用户管理模块进行练习。
用户管理模块
我写的用户管理模块大致可以分为三块个模块
- tools工具模块:一些通用的工具。
- manager_user:该程序用到的子模块。
- main:主函数。
1.先创建各模块对应的.c .h文件。
2.将用到的工具函数在tools.h头文件中声明,在tools.c中定义。之后编译根据错误提醒添加头文件。
tools.h
#ifndef TOOLS_H
#define TOOLS_H
#include <getch.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
//获取指令
int get_cmd(char start,char end);
char* get_str(char* str,size_t size);
void show_msg(const char* msg,float sec);
void anykey_continue(void);
char* get_passwd(char* passwd,size_t size);
#endif//TOOLS_H
tools.c
#include "tools.h"
//获取指令
int get_cmd(char start,char end)
{
puts("===========================");
printf("请输入指令");
while(1)
{
int cmd =getch();
if(start <= cmd && cmd <= end)
{
printf("%c\n",cmd);
return cmd;
}
}
}
char* get_str(char* str,size_t size)
{
assert(NULL!=str && size>1);
size_t len;
while(1)
{
len = strlen(fgets(str,size,stdin));
if(1==len)
printf("\n输入不能为空,请重新输入:");
else
break;
}
if('\n' == str[len-1])
str[len-1] = '\0';
else
while('\n' != getchar());
return str;
}
void show_msg(const char* msg,float sec)
{
printf("\033[01;32m%s\033[00m\n",msg);
usleep(sec*1000000);
}
void anykey_continue(void)
{
puts("按任意键继续...");
getch();
}
char* get_passwd(char* passwd,size_t size)
{
int i = 0;
while(i < size-1)
{
passwd[i] = getch();
// 读取到退格键
if(127 == passwd[i])
{
// 数组中有已输入密码
if(i > 0)
{
// 删除一位密码
i--;
printf("\b \b");
}
continue;
}
i++;
printf("*");
}
passwd[size-1] = '\0';
printf("\n");
return passwd;
}
3.同理完成manager_user.h和manager_user.c
- 注意:为了防止头文件互相包含、递归包含,多文件编程可以写一个type.h的头文件只用于类型设计如:结构体、联合、枚举、宏常量、宏函数,把这些会在多个文件中被用到的东西全都写在一个头文件中方便调用。
我这里只有一个manager_user会用到所以我就在manager_user.h中定义不多写一个头文件了。
manager_user.h
#ifndef MANAGER_USER_H
#define MANAGER_USER_H
#include "tools.h"
#define USER_MAX 100
enum
{
nosuo =1,
suo =2,
};
//用户名 密码 联系方式 是否锁定
typedef struct Id
{
char name[20];
char password[7];
char phone[30];
char lock;
}Id;
extern Id id[USER_MAX];
extern size_t cnt;
extern size_t cnt_yz;
//写入数据
void wfp(void);
//读取数据
void rfp(void);
int name_query(char* str);
//注册用户
void enroll(void);
//输入密码
int goup_password(void);
//登录界面显示
void show_goup(void);
//注销用户
void logoff(void);
//修改信息
void revise(void);
//用户登录
void goup(void);
//显示用户列表
void show_all(void);
//显示菜单。
void show_ml(void);
#endif//MANAGER_USER_H
4.同理完成main.c
#include "manager_user.h"
int main(int argc,const char* argv[])
{
rfp();
for(;;)
{
show_ml();
switch(get_cmd('1','4'))
{
case '1': enroll(); break;
case '2': goup(); break;
case '3': show_all(); break;
case '4': wfp();return 0;
}
}
}
5.编译检查五个文件能否是否有语法错误。
6.创建Makefile编译
FLAG=-Wall -Werror
TARGE=manager
OBJECT=main.o tools.o manager_user.o
$(TARGE):$(OBJECT)
$(CC) $(OBJECT) -o $(TARGE)
main.o:%.o:%.c manager_user.h
$(CC) $(STD) $(FLAG) -c $<
tools.o:%.o:%.c tools.c tools.h
$(CC) $(STD) $(FLAG) -c $<
manager_user.o:%.o:%.c manager_user.c manager_user.h tools.h
$(CC) $(STD) $(FLAG) -c $<
clean:
rm -rf $(OBJECT) $(TARGE)
rm -rf .h.gch
7.键入make命令
编译无误后。