C语言实现通讯录

几点说明

  • 前置知识:结构体指针枚举
  • 本文只有代码,但代码中注释足够详细
  • 本程序以项目形式呈现,如何创建项目在不同IDE中有所不同,请自行解决

main.c文件(主程序)

//引用game.h头文件(在最后)
#include "game.h"

int main(){
	menu();
	
	//创建通讯录,并赋空值 
	contact con = {0};  //通讯录的初始化 
	contactInit(&con);
	while(1){
		int op = chooseOption();
		switch(op){
			case EXIT:  //退出
				Exit(&con);
				return 0;
			case ADD:  //添加联系人
				Add(&con);
				break;
			case DELE:  //删除联系人
				Delete(&con);
				break;
			case SEARCH:  //查找联系人
				Search(&con);
				break;
			case MODIFY:  //修改联系人信息
				Modify(&con);
				break;
			case SORT:  //将联系人按姓名顺序排序
				Sort(&con);
				break;
			case SHOW:  //展示全部联系人
				Show(&con);
				break;
		}
	}

	return 0;
}

func.c文件(函数实现)

#include "game.h"

//设置控制台光标位置 
//看不懂可以将Pos相关内容(本函数和menu()函数中部分)全部删除,无影响 
void Pos(int x, int y){
	COORD pos;
	pos.X = x;
	pos.Y = y;
	
	HANDLE HandleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(HandleOutput, pos);
}

//菜单界面 
void menu(){
	Pos(40, 4);
	printf("*******************************\n");
	Pos(40, 5);
	printf("**********  1 EXIT   **********\n");
	Pos(40, 6);
	printf("**********  2 ADD    **********\n");
	Pos(40, 7);
	printf("**********  3 Delete **********\n");
	Pos(40, 8);
	printf("**********  4 Search **********\n");
	Pos(40, 9);
	printf("**********  5 Modify **********\n");
	Pos(40, 10);
	printf("**********  6 Sort   **********\n");
	Pos(40, 11);
	printf("**********  7 Show   **********\n");
	Pos(40, 12);
	printf("*******************************\n");
}

//选择操作 
int chooseOption(){
	printf("请输入您要进行的操作:");
	int x;
	scanf("%d", &x);
	return x;
}

//通讯录初始化 
void contactInit(contact* con){
	//以二进制只读方式打开文件 
	FILE* pf = fopen("contact.txt", "rb");
	if(!pf){
		//如果打开错误,则返回报错语句 
		printf("%s\n", strerror(errno));
		return;
	}
	else{
		//一定要注意内存的分配!很容易忽略 
		con->data = (conInfo*)malloc(MAX_NUMBER * sizeof(conInfo));
		//创建临时通讯录成员结构体,用以读取文件中的信息 
		conInfo temp = {0};
		while(fread(&temp, sizeof(conInfo), 1, pf)){
			//C语言支持将一个结构体赋值给另一个结构体(同类) 
			con->data[con->size ++] = temp; 
		}
		//关闭文件 
		fclose(pf);
		//将文件指针置为NULL(这里pf指向的地址已经没有意义,防止后续无意间使用pf指针) 
		pf = NULL;
	}
}

void Exit(contact* con){
	//以二进制写入模式打开文件 
	FILE* pf = fopen("contact.txt", "wb");
	if(!pf){
		//打印错误信息(::是约定俗成的分隔符,没有实际含义) 
		printf("Save error::%s\n", strerror(errno));
		return;
	}
	int i;
	for(i = 0; i < con->size; i ++ ){
		//文件以"wb"方式打开,则fwrite() 
		fwrite(con->data + i, sizeof(conInfo), 1, pf);
	}
	fclose(pf);
	pf = NULL;
}

void Add(contact* con){
	if(con->size >= MAX_NUMBER) printf("通讯录已满");
	printf("请输入姓名:");
	scanf("%s", con->data[con->size].name);
	printf("请输入年龄:");
	scanf("%d", &con->data[con->size].age);
	printf("请输入电话:");
	scanf("%s", con->data[con->size].phone);
	con->size ++;
	printf("增加联系人成功\n");
}

void Delete(contact* con){
	printf("请输入要删除的联系人的姓名:");
	char deleteName[20];
	scanf("%s", deleteName);
	int i, flag = 0;  //flag用来标记是否存在该联系人 
	for(i = 0; i < con->size; i ++ )
		if(!strcmp(deleteName, con->data[i].name)){  //strcmp()函数比较姓名是否相同 
			flag = 1;
			for(i; i < con->size - 1; i ++ )
				con->data[i] = con->data[i + 1];  //将后续结构体成员前移,覆盖删除内容 
			con->size --;
			printf("删除成功\n");
		}
	if(!flag) printf("该联系人不存在\n");
}

void Search(contact* con){
	printf("请输入要查找的联系人的姓名:");
	char findName[20];
	scanf("%s", findName);
	int i, flag = 0;
	for(i = 0; i < con->size; i ++ )
		if(!strcmp(findName, con->data[i].name)){
			printf("查找成功\n");
			printf("姓名:%s\n", con->data[i].name); 
			printf("年龄:%d\n", con->data[i].age); 
			printf("电话:%s\n", con->data[i].phone); 
			flag = 1;
		}
		if(!flag)
			printf("该联系人不存在\n");
}

void Modify(contact* con){
	printf("请输入要修改的联系人的姓名:");
	char findName[20];
	scanf("%s", findName);
	int i;
	for(i = 0; i < con->size; i ++ )
		if(!strcmp(findName, con->data[i].name)){
			printf("请输入姓名:");
			scanf("%s", con->data[i].name);
			printf("请输入年龄:");
			scanf("%d", &con->data[i].age);
			printf("请输入电话:");
			scanf("%s", con->data[i].phone);
		}
		else
			printf("该联系人不存在\n");
}

//const void* 为C语言规定的传参方式 
int compare(const void* con1, const void* con2){
	//进行指针的强制类型转换,注意(conInfo*)con->name的方式是错误的
	//这样的话是先->后(conInfo*) 
	return strcmp(((conInfo*)con1)->name, ((conInfo*)con2)->name);
}
void Sort(contact* con){
	//qsort的四个参数分别为:首地址、个数、每个的大小、比较函数 
	qsort(con->data, con->size, sizeof(con->data[0]), compare);
	printf("排序完成!\n");
}

void Show(contact* con){
	int i;
	for(i = 0; i < con->size; i ++ )
		printf("%s %d %s\n", con->data[i].name, con->data[i].age, con->data[i].phone);
}

game.h文件(头文件)

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <string.h>

#define MAX_NUMBER 1000  //最大成员数
#define MAX_NAME 20  //最长名字
#define MAX_PHONE 20  //最长电话号码 

typedef struct conInfo{
	char name[MAX_NAME];
	int age;
	char phone[MAX_PHONE];
}conInfo;

typedef struct contact{
	conInfo* data;
	int size;
}contact;

//枚举,用单词替换常数,增强程序可读性与可维护性 
enum Option
{
	EXIT = 1,
	ADD,
	DELE,
	SEARCH,
	MODIFY,
	SORT,
	SHOW
}input;

void Pos(int x, int y);
void menu();
int chooseOption();
void Exit(contact* con);
void contactInit(contact* con);
void Add(contact* con);
void Delete(contact* con);
void Search(contact* con);
void Modify(contact* con);
void Show(contact* con);
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值