项目要求:
通讯录:电话 姓名 级别
以二维数据存储:
char tle[100][12]
char name[100][10]
char level[100]
存储上下为100人,电话11位,姓名一个中文三位(Linux下),级别用于表示重要程度,也可作为判断标志
实现功能如下:
1.添加联系人
2.删除联系人
3.模糊查找联系人
4.修改联系人
5.显示全部联系人
6.退出
运行环境为linux(gcc)
请斧正
在没学结构体和文件读写前:
tool.h
//tool.h (five stars)基础函数,可通用移植
#ifndef TOOL_H //头文件卫士,防止头文件重复包含
#define TOOL_H
#include<getch.h>
#include<stdio.h>
#include<string.h>
int get_cmd(char start,char end);
char* get_str(char* str,size_t size);
void anykey_continue(void);
#endif //tool.h
tool.c
//tool.c
#include"tool.h"
int get_cmd(char start,char end)//从键盘中读取按键,起始终止位置为ASCII表字符
{
puts("------------------");
printf("请输入指令:");
for(;;)
{
char cmd = getch();
if(start <= cmd && cmd <= end)//接收判断
{
printf("%c\n",cmd);
return cmd;
}
}
}
char* get_str(char* str,size_t size)//优化fgets函数,防止换行符的读取和多余数据残留输入缓冲区
{
// 限制输入的字符度
fgets(str,size,stdin);
// 计算实际输入的字符数量
size_t len = strlen(str);
// 判断最一个字符是否是'\n'
if('\n' == str[len-1])
{
// 删除'\n'
str[len-1] = '\0';
}
else
{
// 清理输入缓冲区
stdin->_IO_read_ptr = stdin->_IO_read_end;//在GNU编译环境下
}
return str;
}
void anykey_continue(void)//读取一个字符后可继续操作
{
stdin->_IO_read_ptr = stdin->_IO_read_end;
puts("按任意键继续...");
getch();
stdin->_IO_read_ptr = stdin->_IO_read_end;
}
func.h
//func.h
#ifndef FUNC_H
#define FUNC_H
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include"tool.h"
char name[100][10];
char tel[100][12];
char level[100];
void add(void);
void del(void);
void mod(void);
void find(void);
void list(void);
void menu(void);
#endif //func.h
func.c
//func.c
#include"func.h"
void add(void)//func_1
{
int i = 0;
while(level[i])i++;
printf("请输入姓名:");
get_str(name[i],10);
printf("请输入电话:");
get_str(tel[i],12);
printf("请输入级别:");
scanf("%c",&level[i]);
printf("姓名:%s 电话:%s 级别:%c 添加联系人成功!\n",
name[i],tel[i],level[i]);
sleep(1); //休眠(停留)一秒
}
void del(void)//func_2
{
char key[10];
printf("请输入要删除的联系人姓名:");
get_str(key,10);
for(int i=0; i<100; i++)
{
if(level[i] && !strcmp(key,name[i]))
{
printf("姓名:%s 电话:%s 级别:%c 删除联系人成功!\n",name[i],tel[i],level[i]);
level[i] = 0;
sleep(1);
return;
}
}
printf("未找到联系人,删除失败!\n");
sleep(1);
}
void mod(void)//func_3
{
char key[10];
printf("请输入要修改的联系人姓名:");
get_str(key,10);
for(int i=0; i<100; i++)
{
if(level[i] && !strcmp(key,name[i]))
{
puts("请重新输入联系人信息!");
printf("请输入姓名:");
get_str(name[i],10);
printf("请输入电话:");
get_str(tel[i],12);
printf("请输入级别:");
scanf("%c",&level[i]);
printf("姓名:%s 电话:%s 级别:%c 修改联系人成功!\n",name[i],tel[i],level[i]);
sleep(1);
return;
}
}
printf("未找到联系人,无法修改!\n");
sleep(1);
}
void find(void)//func_4
{
char key[12];
printf("请输入要查询的关键字:");
get_str(key,12);
for(int i=0; i<100; i++)
{
if(level[i] && (strstr(name[i],key) || strstr(tel[i],key)))
{
printf("姓名:%s 电话:%s 级别:%c \n",name[i],tel[i],level[i]);
}
}
anykey_continue();
}
void list(void)//func_5显示
{
for(int i=0; i<100; i++)
{
if(level[i])
{
printf("姓名:%s 电话:%s 级别:%c \n",name[i],tel[i],level[i]);
}
}
anykey_continue();
}
void menu(void)//show_menu
{
system("clear");
puts("*****欢迎使用通讯录*****");
puts("1、添加联系人");
puts("2、删除联系人");
puts("3、修改联系人");
puts("4、查询联系人");
puts("5、显示联系人");
puts("6、退出");
}
main.c
//main.c
#include<stdio.h>
#include<stdlib.h>
#include"tool.h"
#include"func.h"
int main()
{
for(;;)
{
system("clear"); //清屏
menu();
switch(get_cmd('1','6'))
{
case '1': add(); break;
case '2': del(); break;
case '3': mod(); break;
case '4': find(); break;
case '5': list(); break;
case '6': return 0;
}
}
}
当学了结构体和文件读写后
tool.h
//tool.h (five stars)基础函数,可通用移植
#ifndef TOOL_H //头文件卫士,防止头文件重复包含
#define TOOL_H
#include<getch.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
int get_cmd(char start,char end);
char* get_str(char* str,size_t size);
void anykey_continue(void);
void show_msg(const char* msg,float sec);
bool yes_or_no(void);
#endif //tool.h
tool.c
//tool.c
#include"tool.h"
int get_cmd(char start,char end)//从键盘中读取按键,起始终止位置为ASCII表字符
{
puts("------------------");
printf("请输入指令:");
for(;;)
{
char cmd = getch();
if(start <= cmd && cmd <= end)//接收判断
{
printf("%c\n",cmd);
return cmd;
}
}
}
char* get_str(char* str,size_t size)//优化fgets函数,防止换行符的读取和多余数据残留输入缓冲区
{
// 限制输入的字符度
fgets(str,size,stdin);
// 计算实际输入的字符数量
size_t len = strlen(str);
// 判断最一个字符是否是'\n'
if('\n' == str[len-1])
{
// 删除'\n'
str[len-1] = '\0';
}
else
{
// 清理输入缓冲区
stdin->_IO_read_ptr = stdin->_IO_read_end;//在GNU编译环境下
}
return str;
}
void anykey_continue(void)//读取一个字符后可继续操作
{
stdin->_IO_read_ptr = stdin->_IO_read_end;
puts("按任意键继续...");
getch();
stdin->_IO_read_ptr = stdin->_IO_read_end;
}
void show_msg(const char* msg,float sec) //显示linux下有限的颜色
{
printf("\033[01;34m%s\033[00m\n",msg);
usleep(sec*1000000); //效果同sleep,以微秒为单位
}
bool yes_or_no(void) //再次确认
{
printf("是否确认此操作(y/n)?");
char cmd = getch();
if('y' == cmd)
puts("y");
else
puts("n");
return 'y'==cmd;
}
func.h
//func.h
#ifndef FUNC_H
#define FUNC_H
#include<stdio.h>
#include"tool.h"
// 定义最大联系人数量
const size_t CON_MAX;
const float WAIT_SEC;
// 设计联系人结构体关重定义类型
typedef struct Contacts
{
char name[10];
char tel[12];
char level;
}Contacts;
// 定义联系人结构指针
Contacts* conp;
// 定义联系人数量变量
size_t con_count;
void add_con(void);
void del_con(void);
void mod_con(void);
void find_con(void);
void list_con(void);
void show_con(const Contacts* con);
void file_scanf(Contacts* sp);
void file_printf(Contacts* conp);
#endif //func.h
func.c
//func.c
#include"func.h"
#include<string.h>
#include<unistd.h>
const size_t CON_MAX=100;
const float WAIT_SEC = 1;
Contacts* conp = NULL;
size_t con_count = 0;
void show_con(const Contacts* con)
{
printf("姓名:%s 电话:%s 级别:%c\n",con->name,con->tel,con->level);
}
void add_con(void)
{
if(con_count >= CON_MAX)
{
show_msg("系统已满,无法添加!",WAIT_SEC);
return;
}
int i = 0;
while(conp[i].level) i++;
printf("请输入姓名:");
get_str(conp[i].name,sizeof(conp[i].name));
printf("请输入电话:");
get_str(conp[i].tel,sizeof(conp[i].tel));
printf("请输入级别:");
scanf("%c",&conp[i].level);
show_con(conp+i);
show_msg("添加联系成功!",WAIT_SEC);
con_count++;
}
void del_con(void)
{
char key[12];
printf("请输入要删除的联系人姓名:");
get_str(key,sizeof(key));
for(int i=0; i<CON_MAX; i++)
{
if(conp[i].level && !strcmp(key,conp[i].name))
{
show_con(conp+i);
if(yes_or_no())
{
show_msg("删除成功!",WAIT_SEC);
con_count--;
}
else{
show_msg("取消操作!",WAIT_SEC);
return;
}
}
}
show_msg("未找到联系人,删除失败!",WAIT_SEC);
}
void mod_con(void)
{
char key[10];
printf("请输入要修改的联系人姓名:");
get_str(key,10);
for(int i=0; i<CON_MAX; i++)
{
if(conp[i].level && !strcmp(key,conp[i].name))
{
puts("请重新输入联系人信息!");
printf("请输入姓名:");
get_str(conp[i].name,10);
printf("请输入电话:");
get_str(conp[i].tel,12);
printf("请输入级别:");
scanf("%c",&conp[i].level);
show_con(conp+i);
sleep(1);
return;
}
}
printf("未找到联系人,无法修改!\n");
sleep(1);
return ;
}
void find_con(void)
{
char key[12];
printf("请输入要查询的关键字:\n");
get_str(key,12);
for(int i=0; i<CON_MAX; i++)
{
if(conp[i].level && (strstr(conp[i].name,key) || strstr(conp[i].tel,key)))
{
show_con(conp+i);
}
}
anykey_continue();
}
void list_con(void)
{
for(int i=0; i<CON_MAX; i++)
{
if(conp[i].level)
{
show_con(conp+i);
}
}
anykey_continue();
}
void file_scanf(Contacts* conp)//文件读取
{
FILE* fp= fopen("/home/qmxxd/通讯/通讯结构/通信结构/Contacts.txt", "a+");
if (NULL == fp)
{
printf("文件打开失败!\n");
return ;
}
int i=0;
while (0<fscanf(fp, "姓名:%s 电话:%s 级别:%c\n",conp[i].name,&(conp[i].tel),&(conp[i].level)))
{
//printf( "姓名:%s 电话:%s 级别:%c\n",conp[i].name,conp[i].tel,conp[i].level);
con_count++;
i++;
}
fclose(fp);
}
void file_printf(Contacts* conp)//文件写入
{
FILE* fp= fopen("/home/qmxxd/通讯/通讯结构/通信结构/Contacts.txt", "w+");
if (NULL == fp)
{
printf("文件打开失败!\n");
return ;
}
int i=0;
while (i<con_count)
{
fprintf(fp, "姓名:%s 电话:%s 级别:%c\n",conp[i].name,conp[i].tel,conp[i].level);
i++;
}
fclose(fp);
}
main.c
//main.c
#include<stdio.h>
#include<stdlib.h>
#include"tool.h"
#include"func.h"
int main(int argc,const char* argv[])
{
conp=calloc(CON_MAX,sizeof(Contacts));
file_scanf( conp);
// 为联系人结构数组分配堆内
for(;;)
{
system("clear");
puts("1、添加 2、删除");
puts("3、修改 4、查询");
puts("5、遍历 6、退出并保存");
switch(get_cmd('1','6'))
{
case '1': add_con(); break;
case '2': del_con(); break;
case '3': mod_con(); break;
case '4': find_con(); break;
case '5': list_con(); break;
case '6': file_printf( conp);return 0;
}
}
}