【c语言第一个项目】通讯录实现&优化

项目要求:
通讯录:电话 姓名 级别
以二维数据存储:
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;
		}
	}
	
}


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值