C语言项目实战:通讯录管理系统

简介

项目名称:通讯录管理系统

实现功能:

1.增加联系人信息

2.删除联系人信息

3.查找联系人信息

4.修改联系人信息

        这是一个简单的C语言实战项目,目的在于练习C语言中枚举、结构体、数组、指针以及各种库函数的灵活运用

        该项目也是数据结构与算法中线性表的应用实例,本文使用了顺序表的方法实现通讯录的管理

线性表

        关于线性表的相关知识,我会在另一篇文章中进行讲述。

联系人存储实现

        第一步:创建一个用于存储联系人信息的结构体

#define NameLength   20     //名字的最大长度
#define PhoneLength  20     //电话号码的最大长度

typedef struct
{
    char ContactName[NameLength];
    char PhoneNumber[PhoneNumberLength];
}ContactPerson;

        第二步:创建一个顺序表,用于整合所有的联系人信息

typedef struct
{
    ContactPerson contact_person;    //联系人信息
    int length;                      //记录当前顺序表的长度,即联系人数目
}AddressBook;

        第三步:初始化顺序表,即为顺序表分配一个指定大小的内存

#define MAXSIZE    100 //最大长度

enum Status           //用于记录执行状态的枚举,增加程序的可读性
{
    Fail,
    Success
};


/*
输入:一个AddressBook数据类型的顺序表 
输出:程序执行的结果(成功或者失败)
*/
Status AddressBook_Init(AddressBook &L)
{
    L.contact_person=(ContactPerson*)malloc(sizeof(ContactPerson)*MAXSIZE); 
    //为指定的顺序表动态分配MAXSIZE个AddressBook类型所需大小的内存
    //可以理解为把L变成了一个数组,这句代码执行完后L变成了L.contact_person[MAXSIZE]
    //L的内存放在了堆区

    if(L == NULL)  
    {
        return Fail;  //如果分配失败,malloc会返回NULL,以此判断内存是否分配成功
    }

    L.length = 0;

    return Success;
}

增删查改实现

取值

        实现原理:通过联系人在通讯录中的指定位置“position”进行锁定,并通过形参“e”传递该联系人的信息


/*
 输入:
    1.L:通讯录顺序表
    2.position:联系人在通讯录中的位置信息
    3.e:通过e传递查询到的联系人的信息
输出:程序执行结果(成功或者失败)
*/
Status AddressBook_getContact(AddressBook L,int position, ContactPerson& e)
{
    int i;
    
    if(i < 1 || i > L.length) return Fail; //判断输入是否合法

    strcpy(L.contact_person[position - 1].ContactName, e.ContactName);
    strcpy(L.contact_person[position - 1].PhoneNumber, e.PhoneNumber);
    /*
        strcpy(a,b);将字符串b复制一份给a(注意:这里是字符串)
        将查询到的联系人姓名和电话复制给e
    */

    return Success;
}

查找

        方法1:根据姓名查找。通过输入的姓名“e”从表头开始依次遍历,如果查找成功则通过输入的“p”传递该联系人在通讯录中的存储位置

/*
输入:
    1.L:通讯录顺序表
    2.e:姓名
    3.p:通过p传递该联系人在通讯录中的位置信息
*/
Status AddressBook_searchName(AddressBook L, char* e, int& p)
{
    int i;
    int j;

    for(i = 0;i = L.length - 1;i++)
    {
        j = strcmp(L.contact_person[i].ContactName, e);
        
        if (j == 0)
        {
	        p = i + 1;
	        return Success;
        }  
    }
    /*
        strcmp(a,b);比较a和b两个字符串是否相等,如果相等则返回0,不等返回非0
    */

    return Success;
}

        方法2:根据电话号码查找。通过输入的电话号码“e”从表头开始依次遍历,如果查找成功则通过“p”传递该联系人在通讯录中所在的位置。


Status AddressBook_searchNumber(AddressBook L, char* e, int& p)
{
    int i;
    int j;

    for(i=0;i<L.length-1;i++)
    {
        j=strcmp(L.contact_person[i].PhoneNumber,e);
        
        if(j==0) 
        {
            p=i+1;
            return Success;
        }
    }

    return Fail;
}

插入

        实现原理:输入一个指定的位置“position”,接着将这个指定位置以及在它之后的元素依次向后移,把这个指定的位置空出来,然后插入联系人信息“e”。

/*
输入:
    1.L:通讯录顺序表
    2.position:指定的位置
    3.e:联系人的信息
*/
Status AddressBook_Insert(AddressBook& L, int position, ContactPerson e)
{
    int i;

    if(position<1||position>L.length) return Fail;//判断输入是否合法,增加程序的健壮性

    /*
    从表尾元素开始至指定位置结束,所有元素依次向后移动一个位置。
    */
    for(i=L.length-1;i>=position-1;i--)
    {
        strcpy(L.contact_person[i+1].ContactName,L.contact_person[i].ContactName);
        strcpy(L.contact_person[i+1].PhoneNumber,L.contact_person[i].PhoneNumber);
    }    

    //移动结束后在指定位置插入联系人信息
    strcpy(L.contact_person[position-1].ContactName,e.ContactName);
    strcpy(L.contact_person[position-1].PhoneNumber,e.PhoneNumber);
    L.length += 1;

    return Success;
}

删除

        实现原理:要将指定的位置“position”上的联系人信息删除,只需要把“position+1”上的联系人信息覆盖到“position”上,即将“position”往后的元素依次向前移动。

Status AddressBook_Delete(AddressBook& L, int position)
{
    int i;    

    if(position < 1 || position > L.length) return Fail;

    /*
    从需要删除的那个位置开始,后面的元素依次向前移动即达到了删除目的    
    */
    for(i = position-1;i < L.length-1;i++)
    {
        strcpy_s(L.contact_person[i].ContactName, L.contact_person[i + 1].ContactName);
		strcpy_s(L.contact_person[i].PhoneNumber, L.contact_person[i + 1].PhoneNumber);
    }

    L.length -= 1;

    return Success.
}

修改

        实现原理:首先获取输入的字符串长度,依次对该字符串的每个字符进行判断,如果出现非数字的字符那么就判定输入的这个字符串为姓名,否则就为电话号码。

        再根据输入的姓名或者电话号码去通讯录中查找,获取该联系人在表中的位置

        最后将输入的联系人新信息“e“更新到这个位置上

/*这部分代码是后加的,在文章最后的源代码中并没有出现,但实现操作一致*/
#define isName         0       
#define isPhoneNumber  1
/*
输入:
    1.通讯录顺序表
    2.姓名或者电话号码
    3.联系人的新信息
*/
Status AddressBook_Change(AddressBook &L,char* str,ContactPerson e)
{
    int i;
    int j;
    int p;
    int name_or_number;     //0为姓名,1为数字,也可以用上面预定义的方式增加可读性

    /*
    strlen(a);获取字符串a的长度(不包含'\0')
    对字符换str中的每一个字符进行判断,只要不是数字就判断输入的是姓名
    */
    j = strlen(str);
    for(i = 0;i < j-1;i++)
    {
        if(str[i] > '9' || str[i] < '0')
        {
            name_or_number=isName;
        }
        else
        {
            name_or_number=isPhoneNumber;
        }
    }

    //根据姓名或者电话号码查询该联系人在表中的位置
    if(name_or_number == isName)
    {
        AddressBook_searchName(L,str,p);    
    }

    if(name_or_number == isPhoneNumber)
    {
        AddressBook_searchNumber(L,str,p);
    }

    //更新联系人信息       
    strcmp(L.contact_person[p-1].ContactName,e.ContactName);
    strcmp(L.contact_person[p-1].PhoneNumber,e.PhoneNumber;

    return Success;
}

整理汇总

头文件AddressBook.h

        关于代码里的注释为什么一会是英文一会是中文。因为这个项目我本来是打算用于熟悉线性表的操作所以一开始文件名为LinearTable,并且本人有在写代码时练习英语的习惯,所以一开始代码里的注释全是英文的,如果大家仔细阅读注释就会发现里面有很多语法错误,还请大家见谅。在之后写文章对代码进行整理的时候,为了便于大家阅读就把注释换成了中文,所以下面的代码中用中文注释的代码全部都是后加的。

/*
Author:CmeHY
*/
#ifndef LINEARTABLE_H
#define LINEARTABLE_H

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

#define MAXSIZE		 100		//The maxmum size of sequence list.
#define NumberLength 20
#define NameLength	 20

#define isName         0       
#define isPhoneNumber  1

//Other Operation
enum Status
{
	Fail,
	Success
};

//Description
typedef struct
{
	char ContactName[NameLength];
	char PhoneNumber[NumberLength];
}ContactPerson;

typedef struct
{
	ContactPerson* contact_person; //The base address of the storage space.
	int length;  //Current length.
}AddressBook;

/* Function Declare */
Status AddressBook_Init(AddressBook& L);
Status AddressBook_getContact(AddressBook L, int position, ContactPerson& e);
Status AddressBook_searchName(AddressBook L, char* e, int& p);
Status AddressBook_searchNumber(AddressBook L, char* e, int& p);
Status AddressBook_Insert(AddressBook& L, int position, ContactPerson e);
Status AddressBook_Delete(AddressBook& L, int position);
Status AddressBook_Change(AddressBook& L, char* str, ContactPerson e); //这是后加的,主函数那个文件没有用到

#endif // !LINEARTABLE_H

源文件AddressBook.c

#include "LinearTable.h"
/*
Author:CmeHY
*/

/*
1.Initialize:
	The initialization operation of sequence list is creating an empty list.
Step:
	First->Allocate an array space of a predefined size for the sequence
		   list and make elem points to the base address of this space.
	Second->Set the current length of the list to 0.
*/
Status AddressBook_Init(AddressBook &L)
{
	L.contact_person = (ContactPerson*)malloc(sizeof(ContactPerson)*MAXSIZE);

	if (L.contact_person == NULL) return Fail;

	L.length = 0;

	return Success;
}

/*
2.Get value:
	The value operation is according to the specified position number
	to obtain the value of the relevant data element which is in the 
	sequence list.
Step:
	First->Judge if the specified position number is reasonable,if it is
		   unreasonalbe,then return "Error".
	Second->If the sepcified position number is reasonalbe,then transfer
			the relevant value through "e".
*/
Status AddressBook_getContact(AddressBook L,int position, ContactPerson& e)
{
	int j;

	if (position<1 || position>L.length) return Fail;

	j = position - 1;
	
	e = L.contact_person[j];

	return Success;
}

/*
3.Search:
	According to the specified value of element "e" search for the first 
	element which is equal to "e".If search successfully,then return 
	the position number of the element which is in the list,otherwise 
	return 0.
Step:
	First->Compare in turn with "e" from the first element ,if find the 
		   element which is equal to "e",then return the position 
		   number of this element through "p".
	Second->If not find the element which is equal to "e" after search 
			for all the list ,then return 0.
*/
Status AddressBook_searchName(AddressBook L, char* e, int& p)
{
	int i;
	int j;

	if (strlen(e) + 1 > NameLength) return Fail;

	for (i = 0; i < L.length - 1; i++)
	{
		j = strcmp(L.contact_person[i].ContactName, e);

		if (j == 0)
		{
			p = i + 1;
			return Success;
		}
	}

	return Fail;
}

Status AddressBook_searchNumber(AddressBook L, char* e, int& p)
{
	int i;
	int j;

	if (strlen(e) + 1 > NumberLength) return Fail;

	for (i = 0; i < L.length; i++)
	{
		j = strcmp(L.contact_person[i].PhoneNumber, e);

		if (j == 0)
		{
			p = i + 1;
			return Success;
		}
	}

	return Fail;
}

/*
4.Insert:
	Insert operation of a linear list is inserting a new data element 
	at the specified position in the list.
Step:
	First->Judge if the specified position is reasonalbe.If not,
		   return "Fail".
	Second->Judge if the storage space is overflow.If not,retrun "Fail".
	Third->Move elements from "n" to the specified position one position
		   backward in turn.
	Fourth->Insert new element "e" on the specified position.
*/
Status AddressBook_Insert(AddressBook& L, int position, ContactPerson e)
{
	int i;

	if (position<1 || position>L.length) return Fail;

	for (i = L.length - 1; i >= position - 1; i--)
	{
		strcpy_s(L.contact_person[i + 1].ContactName, L.contact_person[i].ContactName);
		strcpy_s(L.contact_person[i + 1].PhoneNumber, L.contact_person[i].PhoneNumber);
	}

	strcpy_s(L.contact_person[position - 1].ContactName, e.ContactName);
	strcpy_s(L.contact_person[position - 1].PhoneNumber, e.PhoneNumber);
	L.length += 1;

	return Success;
}

/*
5.Delete:
	Delete the specified data element which is on the linear list.
Step:
	First->Delete the specified data element.
	Second->Move data elements from "n" to the specified position
			one position forward in turn.
	Third->Length minus one.
*/
Status AddressBook_Delete(AddressBook& L, int position)
{
	int i;

	if (position<1 || position>L.length) return Fail;

	for (i = position - 1; i < L.length - 1; i++)
	{
		strcpy_s(L.contact_person[i].ContactName, L.contact_person[i + 1].ContactName);
		strcpy_s(L.contact_person[i].PhoneNumber, L.contact_person[i + 1].PhoneNumber);
	}
	L.length -= 1;

	return Success;
}


Status AddressBook_Change(AddressBook& L, char* str, ContactPerson e)
{
	int i;
	int j;
	int p;
	int name_or_number;     //0为姓名,1为数字,也可以用上面预定义的方式增加可读性

	/*
	strlen(a);获取字符串a的长度(不包含'\0')
	对字符换str中的每一个字符进行判断,只要不是数字就判断输入的是姓名
	*/
	j = strlen(str);
	for (i = 0; i < j - 1; i++)
	{
		if (str[i] > '9')
		{
			name_or_number = isName;
		}
		else
		{
			name_or_number = isPhoneNumber;
		}
	}

	//根据姓名或者电话号码查询该联系人在表中的位置
	if (name_or_number == isName)
	{
		AddressBook_searchName(L, str, p);
	}

	if (name_or_number == isPhoneNumber)
	{
		AddressBook_searchNumber(L, str, p);
	}

	//更新联系人信息       
	strcmp(L.contact_person[p - 1].ContactName, e.ContactName);
	strcmp(L.contact_person[p - 1].PhoneNumber, e.PhoneNumber);

	return Success;
}

操作界面实现

        用户界面可以根据个人的喜好更改

用户界面

/*Interface Function*/
void PutStr(const char* str,int length,int mode)
{
	int i;
	int j;

	j = strlen(str);

	if (mode == 1)
	{
		for (i = 0; i < length; i++)
		{
			printf("%s", str);
		}

		printf("\n");
	}
	
	if (mode == 0)
	{
		printf("*");

		for (i = 1; i < ((length - j) / 2); i++)
		{
			printf(" ");
		}

		printf("%s", str);

		for (i = 1; i < ((length - j) / 2); i++)
		{
			printf(" ");
		}

		printf("*\n");
	}
}

void UserInterface()
{
	system("cls"); //清屏指令,每进入一个界面清除上一个界面

	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("1.Search a contact. ",80,0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("2.  Add a contact.  ", 80, 0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("3.Delete a contact. ", 80, 0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("4.Change a contact. ", 80, 0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("5.Open the address book.  ", 80, 0);
	PutStr(" ", 80, 1);
	PutStr("*", 80, 1);
}

之后的操作跟这个一致,不再一一赘述

通讯录管理实现

输入判断函数

对用户输入的选择进行判断,并作出反应

/*Function Interface*/
enum functionInterface
{
	userInterface=5,
	searchInterface,
	addInterface,
	deleteInterface,
	changeInterface
};

int user_selection;
int search_selection;
int add_selection;
int delete_selection;
int change_selection;

/*
形参const char* remind和char* remind的区别:前者是一个指向常量的指针后者是一个指向变量的指针
    1.如果形参为const char* remind,则函数在调用时可以直接传递字符串
如:Reminder("Hello World!"),因为这里的字符串是一个常量
    2.如果形参为char* remind,则函数在调用时需要利用一个变量间接传递字符串
如:char n[]="Hello World!"
    Reminder(n);
*/
void Reminder(const char* remind)
{
	system("cls");
	printf("------------------------%s------------------------\n",remind);
	
	printf("<<<------------------------Press enter to exit.------------------------>>>");
	getchar();      //按下回车键退出
	return;
}

void JudgeSelection(functionInterface which_interface)
{
	switch (which_interface)
	{
	case userInterface:
	{
		if (user_selection < 1 || user_selection>5)
		{
			Reminder("Please enter the correct option.");
		}

		break;
	}

	case searchInterface:
	{
		if (search_selection < 1 || search_selection > 2)
		{
			Reminder("Please enter the correct option.");
		}

		break;
	}

	case deleteInterface:
	{
		if (delete_selection < 1 || delete_selection>2)
		{
			Reminder("Please enter the correct option.");
		}

		break;
	}

	case addInterface:
	{
		if (add_selection < 1 || add_selection>2)
		{
			Reminder("Please enter the correct option.");
		}

		break;
	}

	case changeInterface:
	{
		if (change_selection < 1 || change_selection > 3)
		{
			Reminder("Please enter the correct option.");
		}

		break;
	}

	default:
		break;
	}
}

字符串处理函数

        本文利用的是fgets()函数获取键盘输入的字符串。原因在于scanf()函数虽然也可以获取键盘上的字符串,但是对字符串的长度没有限制,存在内存溢出的风险。

        而在使用fgets()函数时也存在一些问题,比如在调用fgets()前需要清空一下键盘的输入缓存区,不然就会把你之前输入的字符错误读入,而且fgets还会读取回车键,所以最后获取的字符串不能直接用还需要删除最后一个回车键。

//清空缓存区
void ClearBuffer()
{
	int c;
	while ((c = getchar()) != '\n' && c != EOF) {}
}

//删除回车键
void DeleteEnter(char* str)
{
	int i = 0;
	int j = strlen(str);
	while (i < j) {
		if (str[i] == '\n') {
			for (int k = i; k < j; k++) {
				str[k] = str[k + 1];
			}
			j--;
		}
		else {
			i++;
		}
	}
}

功能函数

查找联系人

根据用户输入的信息,利用AddressBook_getContact()函数查找联系人的信息,并放在联系人信息缓存区里,最后输出到屏幕

#define according_to_name			1
#define according_to_phoneNumber	2

ContactPerson information_cache;//联系人信息缓存区

void OutputContactInformation(ContactPerson person)
{
	printf("--------------------------Contact Name------------------------->%s\n", person.ContactName);
	printf("--------------------------Phone Number------------------------->%s\n", person.PhoneNumber);
	printf("Press enter to exit.");
	getchar();
}

void SearchFunction()
{
	SearchInterface(); //查找界面
	printf("Please input your choice:");
	scanf_s("%d", &search_selection);

	JudgeSelection(searchInterface);         //判断输入的选项是否正确

	if (search_selection == according_to_name)
	{
		printf("Please enter the name of the contact:");

		ClearBuffer();		//清空输入的缓冲区
		fgets(input_name, sizeof(input_name), stdin); //stdin:标准输入
		DeleteEnter(input_name);			//删除回车键

		if (AddressBook_searchName(address_book, input_name, search_position) == Success)
		{
			AddressBook_getContact(address_book, search_position, information_cache);
			OutputContactInformation(information_cache);
		}
		else
		{
			Reminder("Please enter the correct name of the contact.");
		}
	}

	if (search_selection == according_to_phoneNumber)
	{
		printf("Please enter the phone number of the contact:");

		ClearBuffer();		//清空输入的缓冲区
		fgets(input_phoneNumber, sizeof(input_phoneNumber), stdin); //stdin:标准输入
		DeleteEnter(input_phoneNumber);			//删除回车键

		if (AddressBook_searchNumber(address_book, input_phoneNumber, search_position) == Success)
		{
			AddressBook_getContact(address_book, search_position, information_cache);
			OutputContactInformation(information_cache);
		}
		else
		{
			Reminder("Please enter the correct phone number of the contact.");
		}
	}
}

增加联系人

#define insert_specified_position	1
#define insert_default_position		2

void InsertFunction()
{
	AddInterface();
	printf("Please input your choice:");
	scanf_s("%d", &add_selection);

	JudgeSelection(addInterface);
	if (add_selection == insert_specified_position)      //指定位置
	{
		printf("Please input the specified position:");
		scanf_s("%d", &add_position);

		printf("Please input the name of the contact:");
		ClearBuffer();
		fgets(input_name, sizeof(input_name), stdin);
		DeleteEnter(input_name);
		
		printf("Please input the phone number of the contact:");
		fgets(input_phoneNumber, sizeof(input_phoneNumber), stdin);
		DeleteEnter(input_phoneNumber);

		strcpy_s(information_cache.ContactName, input_name);
		strcpy_s(information_cache.PhoneNumber, input_phoneNumber);

		if (AddressBook_Insert(address_book, add_position, information_cache) == Success)
		{
			Reminder("The contact was added successfully and will be exited soon.");
		}
		else
		{
			Reminder("The contact addition failed.Please enter the correct position.");
		}

	}

	if (add_selection == insert_default_position)         //默认位置(表尾插入)
	{
		printf("Please input the name of the contact:");
		ClearBuffer();
		fgets(input_name, sizeof(input_name), stdin);
		DeleteEnter(input_name);

		printf("Please input the phone number of the contact:");
		fgets(input_phoneNumber, sizeof(input_phoneNumber), stdin);
		DeleteEnter(input_phoneNumber);

		strcpy_s(information_cache.ContactName, input_name);
		strcpy_s(information_cache.PhoneNumber, input_phoneNumber);

		if (AddressBook_Insert(address_book, address_book.length, information_cache) == Success)
		{
			Reminder("The contact was added successfully and will be exit soon.");
		}
		else
		{
			Reminder("The contact addition failed.");
		}
	}
}

删除联系人

void DeleteFunction()
{
	DeleteInterface();

	printf("Please input your choice:");
	scanf_s("%d", &delete_selection);

	JudgeSelection(deleteInterface);

	if (delete_selection == according_to_name)
	{
		printf("Please input the name of the contact:");
		ClearBuffer();
		fgets(input_name, sizeof(input_name), stdin);
		DeleteEnter(input_name);

		if (AddressBook_searchName(address_book, input_name, search_position) == Success)
		{
			AddressBook_Delete(address_book, search_position);
			printf("The contact was deleted successfully.Press any key to exit.");
			getchar();
		}
		else
		{
			Reminder("Please enter the correct name of the contact.");
		}
	}

	if (delete_selection == according_to_phoneNumber)
	{
		printf("Please input the phone number of the contact:");
		ClearBuffer();
		fgets(input_phoneNumber, sizeof(input_phoneNumber), stdin);
		DeleteEnter(input_phoneNumber);

		if (AddressBook_searchNumber(address_book, input_phoneNumber, search_position) == Success)
		{
			AddressBook_Delete(address_book, search_position);
			printf("The contact was deleted successfully.Press any key to exit.");
			getchar();
		}
		else
		{
			Reminder("Please enter the correct phone number of the contact.");
		}
	}
}

修改联系人

#define change_contact_name			 1
#define change_contact_phoneNumber	 2
#define change_contact_nameAndNumber 3

void ChangeFunction()
{
	ChangeInterface();

	printf("Please input your choice:");
	scanf_s("%d", &change_selection);

	JudgeSelection(changeInterface);
	if (change_selection == change_contact_name)           //仅修改姓名
	{
		printf("Please input the old name of the contact:");
		ClearBuffer();
		fgets(old_name, sizeof(old_name), stdin);
		DeleteEnter(old_name);

		if (AddressBook_searchName(address_book, old_name, search_position) == Success)
		{
			printf("Please input the new name of the contact:");
			fgets(new_name, sizeof(new_name), stdin);
			DeleteEnter(new_name);

			strcpy_s(address_book.contact_person[search_position - 1].ContactName, new_name);
			printf("The contact name was changed successfully.\n");
			printf("The new name of contact is-------> %s\n", address_book.contact_person[search_position - 1].ContactName);
			printf("The phone number of contact is---> %s\n", address_book.contact_person[search_position - 1].PhoneNumber);
			getchar();
		}
		else
		{
			Reminder("Please enter the correct name of the contact.");
		}
	}

	if (change_selection == change_contact_phoneNumber)      //进修改电话号码
	{
		printf("Please input the old phone number of the contact:");
		ClearBuffer();
		fgets(old_phoneNumber, sizeof(old_phoneNumber), stdin);
		DeleteEnter(old_phoneNumber);

		if (AddressBook_searchNumber(address_book, old_phoneNumber, search_position) == Success)
		{
			printf("Please input the new phone number of the contact:");
			fgets(new_phoneNumber, sizeof(new_phoneNumber), stdin);
			DeleteEnter(new_phoneNumber);

			strcpy_s(address_book.contact_person[search_position - 1].PhoneNumber, new_phoneNumber);
			printf("The contact phone number was changed successfully.\n");
			printf("The contact name is-------> %s\n", address_book.contact_person[search_position - 1].ContactName);
			printf("The new phone number is---> %s\n", address_book.contact_person[search_position - 1].PhoneNumber);
			getchar();
		}
		else
		{
			Reminder("Please enter the correct name of the contact.");
		}
	}

	if (change_selection == change_contact_nameAndNumber)        //修改姓名和电话号
	{
		printf("Please input the old phone number or old name of the contact:");
		ClearBuffer();
		fgets(unknown, sizeof(unknown), stdin);
		DeleteEnter(unknown);

		if (UnknowJudge(unknown) == isName)
		{
			if (AddressBook_searchName(address_book, unknown, search_position) == Success)
			{
				printf("Please input the new name of the contact:");
				fgets(new_name, sizeof(new_name), stdin);
				DeleteEnter(new_name);

				printf("Please input the new phone number of the contact:");
				fgets(new_phoneNumber, sizeof(new_phoneNumber), stdin);
				DeleteEnter(new_phoneNumber);

				strcpy_s(address_book.contact_person[search_position - 1].ContactName, new_name);
				strcpy_s(address_book.contact_person[search_position - 1].PhoneNumber, new_phoneNumber);

				printf("The contact information was changed successfully.\n");
				printf("The new name of contact is-----------> %s\n", address_book.contact_person[search_position - 1].ContactName);
				printf("The new phone number of contact is---> %s\n", address_book.contact_person[search_position - 1].PhoneNumber);
				getchar();
			}
			else
			{
				Reminder("Please enter the correct name of the contact.");
			}
		}

		if (UnknowJudge(unknown) == isPhoneNumber)
		{
			if (AddressBook_searchNumber(address_book, unknown, search_position) == Success)
			{
				printf("Please input the new name of the contact:");
				fgets(new_name, sizeof(new_name), stdin);
				DeleteEnter(new_name);

				printf("Please input the new phone number of the contact:");
				fgets(new_phoneNumber, sizeof(new_phoneNumber), stdin);
				DeleteEnter(new_phoneNumber);

				strcpy_s(address_book.contact_person[search_position - 1].ContactName, new_name);
				strcpy_s(address_book.contact_person[search_position - 1].PhoneNumber, new_phoneNumber);

				printf("The contact information was changed successfully.\n");
				printf("The new name of contact is-----------> %s\n", address_book.contact_person[search_position - 1].ContactName);
				printf("The new phone number of contact is---> %s\n", address_book.contact_person[search_position - 1].PhoneNumber);
				getchar();
			}
			else
			{
				Reminder("Please enter the correct name of the contact.");
			}
		}
	}
}

通讯录显示

void AddressBookInformation()
{
	int l;
	int i;

	system("cls");
	l = address_book.length;
	for (i = 0; i < l - 1; i++)
	{
		OutputContactInformation_1(address_book.contact_person[i]);
	}

	printf("Press enter to exit.");

	getchar();
}

源代码

        本人用的开发环境是VisualStudio2022,里面的库函数根据编译软件的不同可能有点区别。

比如VS2022中的scanf()函数会提示安全问题,得用scanf_s()

LinearTable.h

/*
Author:CmeHY
*/
#ifndef LINEARTABLE_H
#define LINEARTABLE_H

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

/*                 Operation One:Sequence List                       */
#define MAXSIZE		 100		//The maxmum size of sequence list.
#define NumberLength 20
#define NameLength	 20

#define isName         0       
#define isPhoneNumber  1

//Other Operation
enum Status
{
	Fail,
	Success
};

//Description
typedef struct
{
	char ContactName[NameLength];
	char PhoneNumber[NumberLength];
}ContactPerson;

typedef struct
{
	ContactPerson* contact_person; //The base address of the storage space.
	int length;  //Current length.
}AddressBook;

/* Function Declare */
Status AddressBook_Init(AddressBook& L);
Status AddressBook_getContact(AddressBook L, int position, ContactPerson& e);
Status AddressBook_searchName(AddressBook L, char* e, int& p);
Status AddressBook_searchNumber(AddressBook L, char* e, int& p);
Status AddressBook_Insert(AddressBook& L, int position, ContactPerson e);
Status AddressBook_Delete(AddressBook& L, int position);
Status AddressBook_Change(AddressBook& L, char* str, ContactPerson e); //这是后加的,主函数那个文件没有用到

#endif // !LINEARTABLE_H

LinearTable.c

#include "LinearTable.h"
/*
	Author:CmeHY
*/
/***                Operation One:Sequence List                     ***/
/*
1.Initialize:
	The initialization operation of sequence list is creating an empty list.
Step:
	First->Allocate an array space of a predefined size for the sequence
		   list and make elem points to the base address of this space.
	Second->Set the current length of the list to 0.
*/
Status AddressBook_Init(AddressBook &L)
{
	L.contact_person = (ContactPerson*)malloc(sizeof(ContactPerson)*MAXSIZE);

	if (L.contact_person == NULL) return Fail;

	L.length = 0;

	return Success;
}

/*
2.Get value:
	The value operation is according to the specified position number
	to obtain the value of the relevant data element which is in the 
	sequence list.
Step:
	First->Judge if the specified position number is reasonable,if it is
		   unreasonalbe,then return "Error".
	Second->If the sepcified position number is reasonalbe,then transfer
			the relevant value through "e".
*/
Status AddressBook_getContact(AddressBook L,int position, ContactPerson& e)
{
	int j;

	if (position<1 || position>L.length) return Fail;

	j = position - 1;
	
	e = L.contact_person[j];

	return Success;
}

/*
3.Search:
	According to the specified value of element "e" search for the first 
	element which is equal to "e".If search successfully,then return 
	the position number of the element which is in the list,otherwise 
	return 0.
Step:
	First->Compare in turn with "e" from the first element ,if find the 
		   element which is equal to "e",then return the position 
		   number of this element through "p".
	Second->If not find the element which is equal to "e" after search 
			for all the list ,then return 0.
*/
Status AddressBook_searchName(AddressBook L, char* e, int& p)
{
	int i;
	int j;

	if (strlen(e) + 1 > NameLength) return Fail;

	for (i = 0; i < L.length - 1; i++)
	{
		j = strcmp(L.contact_person[i].ContactName, e);

		if (j == 0)
		{
			p = i + 1;
			return Success;
		}
	}

	return Fail;
}

Status AddressBook_searchNumber(AddressBook L, char* e, int& p)
{
	int i;
	int j;

	if (strlen(e) + 1 > NumberLength) return Fail;

	for (i = 0; i < L.length; i++)
	{
		j = strcmp(L.contact_person[i].PhoneNumber, e);

		if (j == 0)
		{
			p = i + 1;
			return Success;
		}
	}

	return Fail;
}

/*
4.Insert:
	Insert operation of a linear list is inserting a new data element 
	at the specified position in the list.
Step:
	First->Judge if the specified position is reasonalbe.If not,
		   return "Fail".
	Second->Judge if the storage space is overflow.If not,retrun "Fail".
	Third->Move elements from "n" to the specified position one position
		   backward in turn.
	Fourth->Insert new element "e" on the specified position.
*/
Status AddressBook_Insert(AddressBook& L, int position, ContactPerson e)
{
	int i;

	if (position<1 || position>L.length) return Fail;

	for (i = L.length - 1; i >= position - 1; i--)
	{
		strcpy_s(L.contact_person[i + 1].ContactName, L.contact_person[i].ContactName);
		strcpy_s(L.contact_person[i + 1].PhoneNumber, L.contact_person[i].PhoneNumber);
	}

	strcpy_s(L.contact_person[position - 1].ContactName, e.ContactName);
	strcpy_s(L.contact_person[position - 1].PhoneNumber, e.PhoneNumber);
	L.length += 1;

	return Success;
}

/*
5.Delete:
	Delete the specified data element which is on the linear list.
Step:
	First->Delete the specified data element.
	Second->Move data elements from "n" to the specified position
			one position forward in turn.
	Third->Length minus one.
*/
Status AddressBook_Delete(AddressBook& L, int position)
{
	int i;

	if (position<1 || position>L.length) return Fail;

	for (i = position - 1; i < L.length - 1; i++)
	{
		strcpy_s(L.contact_person[i].ContactName, L.contact_person[i + 1].ContactName);
		strcpy_s(L.contact_person[i].PhoneNumber, L.contact_person[i + 1].PhoneNumber);
	}
	L.length -= 1;

	return Success;
}


Status AddressBook_Change(AddressBook& L, char* str, ContactPerson e)
{
	int i;
	int j;
	int p;
	int name_or_number;     //0为姓名,1为数字,也可以用上面预定义的方式增加可读性

	/*
	strlen(a);获取字符串a的长度(不包含'\0')
	对字符换str中的每一个字符进行判断,只要不是数字就判断输入的是姓名
	*/
	j = strlen(str);
	for (i = 0; i < j - 1; i++)
	{
		if (str[i] > '9')
		{
			name_or_number = isName;
		}
		else
		{
			name_or_number = isPhoneNumber;
		}
	}

	//根据姓名或者电话号码查询该联系人在表中的位置
	if (name_or_number == isName)
	{
		AddressBook_searchName(L, str, p);
	}

	if (name_or_number == isPhoneNumber)
	{
		AddressBook_searchNumber(L, str, p);
	}

	//更新联系人信息       
	strcmp(L.contact_person[p - 1].ContactName, e.ContactName);
	strcmp(L.contact_person[p - 1].PhoneNumber, e.PhoneNumber);

	return Success;
}#include "LinearTable.h"
/*
	Author:CmeHY
*/
/***                Operation One:Sequence List                     ***/
/*
1.Initialize:
	The initialization operation of sequence list is creating an empty list.
Step:
	First->Allocate an array space of a predefined size for the sequence
		   list and make elem points to the base address of this space.
	Second->Set the current length of the list to 0.
*/
Status AddressBook_Init(AddressBook &L)
{
	L.contact_person = (ContactPerson*)malloc(sizeof(ContactPerson)*MAXSIZE);

	if (L.contact_person == NULL) return Fail;

	L.length = 0;

	return Success;
}

/*
2.Get value:
	The value operation is according to the specified position number
	to obtain the value of the relevant data element which is in the 
	sequence list.
Step:
	First->Judge if the specified position number is reasonable,if it is
		   unreasonalbe,then return "Error".
	Second->If the sepcified position number is reasonalbe,then transfer
			the relevant value through "e".
*/
Status AddressBook_getContact(AddressBook L,int position, ContactPerson& e)
{
	int j;

	if (position<1 || position>L.length) return Fail;

	j = position - 1;
	
	e = L.contact_person[j];

	return Success;
}

/*
3.Search:
	According to the specified value of element "e" search for the first 
	element which is equal to "e".If search successfully,then return 
	the position number of the element which is in the list,otherwise 
	return 0.
Step:
	First->Compare in turn with "e" from the first element ,if find the 
		   element which is equal to "e",then return the position 
		   number of this element through "p".
	Second->If not find the element which is equal to "e" after search 
			for all the list ,then return 0.
*/
Status AddressBook_searchName(AddressBook L, char* e, int& p)
{
	int i;
	int j;

	if (strlen(e) + 1 > NameLength) return Fail;

	for (i = 0; i < L.length - 1; i++)
	{
		j = strcmp(L.contact_person[i].ContactName, e);

		if (j == 0)
		{
			p = i + 1;
			return Success;
		}
	}

	return Fail;
}

Status AddressBook_searchNumber(AddressBook L, char* e, int& p)
{
	int i;
	int j;

	if (strlen(e) + 1 > NumberLength) return Fail;

	for (i = 0; i < L.length; i++)
	{
		j = strcmp(L.contact_person[i].PhoneNumber, e);

		if (j == 0)
		{
			p = i + 1;
			return Success;
		}
	}

	return Fail;
}

/*
4.Insert:
	Insert operation of a linear list is inserting a new data element 
	at the specified position in the list.
Step:
	First->Judge if the specified position is reasonalbe.If not,
		   return "Fail".
	Second->Judge if the storage space is overflow.If not,retrun "Fail".
	Third->Move elements from "n" to the specified position one position
		   backward in turn.
	Fourth->Insert new element "e" on the specified position.
*/
Status AddressBook_Insert(AddressBook& L, int position, ContactPerson e)
{
	int i;

	if (position<1 || position>L.length) return Fail;

	for (i = L.length - 1; i >= position - 1; i--)
	{
		strcpy_s(L.contact_person[i + 1].ContactName, L.contact_person[i].ContactName);
		strcpy_s(L.contact_person[i + 1].PhoneNumber, L.contact_person[i].PhoneNumber);
	}

	strcpy_s(L.contact_person[position - 1].ContactName, e.ContactName);
	strcpy_s(L.contact_person[position - 1].PhoneNumber, e.PhoneNumber);
	L.length += 1;

	return Success;
}

/*
5.Delete:
	Delete the specified data element which is on the linear list.
Step:
	First->Delete the specified data element.
	Second->Move data elements from "n" to the specified position
			one position forward in turn.
	Third->Length minus one.
*/
Status AddressBook_Delete(AddressBook& L, int position)
{
	int i;

	if (position<1 || position>L.length) return Fail;

	for (i = position - 1; i < L.length - 1; i++)
	{
		strcpy_s(L.contact_person[i].ContactName, L.contact_person[i + 1].ContactName);
		strcpy_s(L.contact_person[i].PhoneNumber, L.contact_person[i + 1].PhoneNumber);
	}
	L.length -= 1;

	return Success;
}


Status AddressBook_Change(AddressBook& L, char* str, ContactPerson e)
{
	int i;
	int j;
	int p;
	int name_or_number;     //0为姓名,1为数字,也可以用上面预定义的方式增加可读性

	/*
	strlen(a);获取字符串a的长度(不包含'\0')
	对字符换str中的每一个字符进行判断,只要不是数字就判断输入的是姓名
	*/
	j = strlen(str);
	for (i = 0; i < j - 1; i++)
	{
		if (str[i] > '9')
		{
			name_or_number = isName;
		}
		else
		{
			name_or_number = isPhoneNumber;
		}
	}

	//根据姓名或者电话号码查询该联系人在表中的位置
	if (name_or_number == isName)
	{
		AddressBook_searchName(L, str, p);
	}

	if (name_or_number == isPhoneNumber)
	{
		AddressBook_searchNumber(L, str, p);
	}

	//更新联系人信息       
	strcmp(L.contact_person[p - 1].ContactName, e.ContactName);
	strcmp(L.contact_person[p - 1].PhoneNumber, e.PhoneNumber);

	return Success;
}

main.h

#include "LinearTable.h"
#include <ctime>

/*Selection Mode*/
#define searchContact	1
#define addContact		2
#define deleteContact	3
#define changeContact	4
#define addressBookInformation 5

#define according_to_name			1
#define according_to_phoneNumber	2

#define insert_specified_position	1
#define insert_default_position		2

#define change_contact_name			 1
#define change_contact_phoneNumber	 2
#define change_contact_nameAndNumber 3

#define isPhoneNumber	1
#define isName			0
/*Function Interface*/
enum functionInterface
{
	userInterface=5,
	searchInterface,
	addInterface,
	deleteInterface,
	changeInterface
};

/*Global Variable*/
AddressBook address_book;
ContactPerson information_cache;

int user_selection;
int search_selection;
int add_selection;
int delete_selection;
int change_selection;

int search_position;
int add_position;

uint32_t timer;

char input_name[NameLength];
char old_name[NameLength];
char new_name[NameLength];
char unknown[20];

char input_phoneNumber[NumberLength];
char old_phoneNumber[NumberLength];
char new_phoneNumber[NumberLength];

/*Function Declare*/
void Test();
void UserInterface();
void SearchInterface();
void AddInterface();
void DeleteInterface();
void ChangeInterface();

void JudgeSelection(functionInterface which_interface); 
int UnknowJudge(char* str);

void Reminder(const char* remind);
void ClearBuffer();
void DeleteEnter(char* str);
void OutputContactInformation(ContactPerson person);

void SearchFunction();
void InsertFunction();
void DeleteFunction();
void ChangeFunction();
void AddressBookInformation();

main.c

#include "main.h"

/*
作者:CmeHY
项目名称:通讯录管理系统

顺序表应用实例:通讯录管理
实现功能:
	1.增加联系人
	2.查找联系人
	3.删除联系人
	4.修改联系人信息
	5.显示所有联系人
*/
int main()
{
	int data_cache;

	timer = 0;
	AddressBook_Init(address_book);
	Test();

	while (1)
	{
		UserInterface();
		printf("Please input your choice:");
		scanf_s("%d", &user_selection);

		JudgeSelection(userInterface);
		ClearBuffer();
		switch (user_selection)
		{
		
		case searchContact:
		{
			SearchFunction();

			break;
		}

		case addContact:
		{
			InsertFunction();

			break;
		}

		case deleteContact:
		{
			DeleteFunction();

			break;
		}

		case changeContact:
		{
			ChangeFunction();

			break;
		}

		case addressBookInformation:
		{
			AddressBookInformation();

			break;
		}
		}
	}
}

ContactPerson e;
/* Test specified function. */
void Test()
{

	strcpy_s(address_book.contact_person[0].ContactName, "ZHY");
	strcpy_s(address_book.contact_person[0].PhoneNumber, "15245");
	address_book.length += 1;

	strcpy_s(e.ContactName, "小白");
	strcpy_s(e.PhoneNumber, "89477411548");
	AddressBook_Insert(address_book, 1, e);

	strcpy_s(e.ContactName, "小明");
	strcpy_s(e.PhoneNumber, "55417411548");
	AddressBook_Insert(address_book, 1, e);

	strcpy_s(e.ContactName, "小黑");
	strcpy_s(e.PhoneNumber, "514515541");
	AddressBook_Insert(address_book, 1, e);
}

/*Interface Function*/
void PutStr(const char* str,int length,int mode)
{
	int i;
	int j;

	j = strlen(str);

	if (mode == 1)
	{
		for (i = 0; i < length; i++)
		{
			printf("%s", str);
		}

		printf("\n");
	}
	
	if (mode == 0)
	{
		printf("*");

		for (i = 1; i < ((length - j) / 2); i++)
		{
			printf(" ");
		}

		printf("%s", str);

		for (i = 1; i < ((length - j) / 2); i++)
		{
			printf(" ");
		}

		printf("*\n");
	}
}

void UserInterface()
{
	system("cls");

	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("1.Search a contact. ",80,0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("2.  Add a contact.  ", 80, 0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("3.Delete a contact. ", 80, 0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("4.Change a contact. ", 80, 0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("5.Open the address book.  ", 80, 0);
	PutStr(" ", 80, 1);
	PutStr("*", 80, 1);
}

void SearchInterface()
{
	system("cls");

	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("1.According to the name.  ", 80, 0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("2.According to the phone number.  ", 80, 0);
	PutStr(" ", 80, 1);
	PutStr("*", 80, 1);
}

void AddInterface()
{
	system("cls");

	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("1.Insert at the specified position. ", 80, 0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("2.Insert at the default position.   ", 80, 0);
	PutStr(" ", 80, 1);
	PutStr("*", 80, 1);
}

void DeleteInterface()
{
	system("cls");

	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("1.According to the name.  ", 80, 0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("2.According to the phone number.  ", 80, 0);
	PutStr(" ", 80, 1);
	PutStr("*", 80, 1);
}

void ChangeInterface()
{
	system("cls");

	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("1.Change the contact name.  ", 80, 0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("2.Change the contact phone number.  ", 80, 0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("3.Change the contact name and phone number.  ", 80, 0);
	PutStr(" ", 80, 1);
	PutStr("*", 80, 1);
}

void Reminder(const char* remind)
{
	system("cls");
	printf("------------------------%s------------------------\n",remind);
	
	printf("<<<------------------------Press enter to exit.------------------------>>>");
	getchar();
	return;
}

void JudgeSelection(functionInterface which_interface)
{
	switch (which_interface)
	{
	case userInterface:
	{
		if (user_selection < 1 || user_selection>5)
		{
			Reminder("Please enter the correct option.");
		}

		break;
	}

	case searchInterface:
	{
		if (search_selection < 1 || search_selection > 2)
		{
			Reminder("Please enter the correct option.");
		}

		break;
	}

	case deleteInterface:
	{
		if (delete_selection < 1 || delete_selection>2)
		{
			Reminder("Please enter the correct option.");
		}

		break;
	}

	case addInterface:
	{
		if (add_selection < 1 || add_selection>2)
		{
			Reminder("Please enter the correct option.");
		}

		break;
	}

	case changeInterface:
	{
		if (change_selection < 1 || change_selection > 3)
		{
			Reminder("Please enter the correct option.");
		}

		break;
	}

	default:
		break;
	}
}

int UnknowJudge(char* str)
{
	int i;
	int j;

	j = strlen(str);
	for (i = 0; i < j - 1; i++)
	{
		if (str[i] > '9') return isName;
	}

	return isPhoneNumber;
}

void ClearBuffer()
{
	int c;
	while ((c = getchar()) != '\n' && c != EOF) {}
}

void DeleteEnter(char* str)
{
	int i = 0;
	int j = strlen(str);
	while (i < j) {
		if (str[i] == '\n') {
			for (int k = i; k < j; k++) {
				str[k] = str[k + 1];
			}
			j--;
		}
		else {
			i++;
		}
	}
}

void OutputContactInformation(ContactPerson person)
{
	printf("--------------------------Contact Name------------------------->%s\n", person.ContactName);
	printf("--------------------------Phone Number------------------------->%s\n", person.PhoneNumber);
	printf("Press enter to exit.");
	getchar();
}

void OutputContactInformation_1(ContactPerson person_1)
{
	int k=100;

	printf("|   Contact Name >> %s\n", person_1.ContactName);
	printf("|   Phone Numbe  >> %s\n", person_1.PhoneNumber);

	while (k--)
	{
		printf("-");
	}

	printf("\n");
}

/*Application Function*/
void SearchFunction()
{
	SearchInterface();
	printf("Please input your choice:");
	scanf_s("%d", &search_selection);

	JudgeSelection(searchInterface);

	if (search_selection == according_to_name)
	{
		printf("Please enter the name of the contact:");

		ClearBuffer();		//清空输入的缓冲区
		fgets(input_name, sizeof(input_name), stdin); //stdin:标准输入
		DeleteEnter(input_name);			//删除回车键

		if (AddressBook_searchName(address_book, input_name, search_position) == Success)
		{
			AddressBook_getContact(address_book, search_position, information_cache);
			OutputContactInformation(information_cache);
		}
		else
		{
			Reminder("Please enter the correct name of the contact.");
		}
	}

	if (search_selection == according_to_phoneNumber)
	{
		printf("Please enter the phone number of the contact:");

		ClearBuffer();		//清空输入的缓冲区
		fgets(input_phoneNumber, sizeof(input_phoneNumber), stdin); //stdin:标准输入
		DeleteEnter(input_phoneNumber);			//删除回车键

		if (AddressBook_searchNumber(address_book, input_phoneNumber, search_position) == Success)
		{
			AddressBook_getContact(address_book, search_position, information_cache);
			OutputContactInformation(information_cache);
		}
		else
		{
			Reminder("Please enter the correct phone number of the contact.");
		}
	}
}

void InsertFunction()
{
	AddInterface();
	printf("Please input your choice:");
	scanf_s("%d", &add_selection);

	JudgeSelection(addInterface);
	if (add_selection == insert_specified_position)
	{
		printf("Please input the specified position:");
		scanf_s("%d", &add_position);

		printf("Please input the name of the contact:");
		ClearBuffer();
		fgets(input_name, sizeof(input_name), stdin);
		DeleteEnter(input_name);
		
		printf("Please input the phone number of the contact:");
		fgets(input_phoneNumber, sizeof(input_phoneNumber), stdin);
		DeleteEnter(input_phoneNumber);

		strcpy_s(information_cache.ContactName, input_name);
		strcpy_s(information_cache.PhoneNumber, input_phoneNumber);

		if (AddressBook_Insert(address_book, add_position, information_cache) == Success)
		{
			Reminder("The contact was added successfully and will be exited soon.");
		}
		else
		{
			Reminder("The contact addition failed.Please enter the correct position.");
		}

	}

	if (add_selection == insert_default_position)
	{
		printf("Please input the name of the contact:");
		ClearBuffer();
		fgets(input_name, sizeof(input_name), stdin);
		DeleteEnter(input_name);

		printf("Please input the phone number of the contact:");
		fgets(input_phoneNumber, sizeof(input_phoneNumber), stdin);
		DeleteEnter(input_phoneNumber);

		strcpy_s(information_cache.ContactName, input_name);
		strcpy_s(information_cache.PhoneNumber, input_phoneNumber);

		if (AddressBook_Insert(address_book, address_book.length, information_cache) == Success)
		{
			Reminder("The contact was added successfully and will be exit soon.");
		}
		else
		{
			Reminder("The contact addition failed.");
		}
	}
}

void DeleteFunction()
{
	DeleteInterface();

	printf("Please input your choice:");
	scanf_s("%d", &delete_selection);

	JudgeSelection(deleteInterface);

	if (delete_selection == according_to_name)
	{
		printf("Please input the name of the contact:");
		ClearBuffer();
		fgets(input_name, sizeof(input_name), stdin);
		DeleteEnter(input_name);

		if (AddressBook_searchName(address_book, input_name, search_position) == Success)
		{
			AddressBook_Delete(address_book, search_position);
			printf("The contact was deleted successfully.Press any key to exit.");
			getchar();
		}
		else
		{
			Reminder("Please enter the correct name of the contact.");
		}
	}

	if (delete_selection == according_to_phoneNumber)
	{
		printf("Please input the phone number of the contact:");
		ClearBuffer();
		fgets(input_phoneNumber, sizeof(input_phoneNumber), stdin);
		DeleteEnter(input_phoneNumber);

		if (AddressBook_searchNumber(address_book, input_phoneNumber, search_position) == Success)
		{
			AddressBook_Delete(address_book, search_position);
			printf("The contact was deleted successfully.Press any key to exit.");
			getchar();
		}
		else
		{
			Reminder("Please enter the correct phone number of the contact.");
		}
	}
}

void ChangeFunction()
{
	ChangeInterface();

	printf("Please input your choice:");
	scanf_s("%d", &change_selection);

	JudgeSelection(changeInterface);
	if (change_selection == change_contact_name)
	{
		printf("Please input the old name of the contact:");
		ClearBuffer();
		fgets(old_name, sizeof(old_name), stdin);
		DeleteEnter(old_name);

		if (AddressBook_searchName(address_book, old_name, search_position) == Success)
		{
			printf("Please input the new name of the contact:");
			fgets(new_name, sizeof(new_name), stdin);
			DeleteEnter(new_name);

			strcpy_s(address_book.contact_person[search_position - 1].ContactName, new_name);
			printf("The contact name was changed successfully.\n");
			printf("The new name of contact is-------> %s\n", address_book.contact_person[search_position - 1].ContactName);
			printf("The phone number of contact is---> %s\n", address_book.contact_person[search_position - 1].PhoneNumber);
			getchar();
		}
		else
		{
			Reminder("Please enter the correct name of the contact.");
		}
	}

	if (change_selection == change_contact_phoneNumber)
	{
		printf("Please input the old phone number of the contact:");
		ClearBuffer();
		fgets(old_phoneNumber, sizeof(old_phoneNumber), stdin);
		DeleteEnter(old_phoneNumber);

		if (AddressBook_searchNumber(address_book, old_phoneNumber, search_position) == Success)
		{
			printf("Please input the new phone number of the contact:");
			fgets(new_phoneNumber, sizeof(new_phoneNumber), stdin);
			DeleteEnter(new_phoneNumber);

			strcpy_s(address_book.contact_person[search_position - 1].PhoneNumber, new_phoneNumber);
			printf("The contact phone number was changed successfully.\n");
			printf("The contact name is-------> %s\n", address_book.contact_person[search_position - 1].ContactName);
			printf("The new phone number is---> %s\n", address_book.contact_person[search_position - 1].PhoneNumber);
			getchar();
		}
		else
		{
			Reminder("Please enter the correct name of the contact.");
		}
	}

	if (change_selection == change_contact_nameAndNumber)
	{
		printf("Please input the old phone number or old name of the contact:");
		ClearBuffer();
		fgets(unknown, sizeof(unknown), stdin);
		DeleteEnter(unknown);

		if (UnknowJudge(unknown) == isName)
		{
			if (AddressBook_searchName(address_book, unknown, search_position) == Success)
			{
				printf("Please input the new name of the contact:");
				fgets(new_name, sizeof(new_name), stdin);
				DeleteEnter(new_name);

				printf("Please input the new phone number of the contact:");
				fgets(new_phoneNumber, sizeof(new_phoneNumber), stdin);
				DeleteEnter(new_phoneNumber);

				strcpy_s(address_book.contact_person[search_position - 1].ContactName, new_name);
				strcpy_s(address_book.contact_person[search_position - 1].PhoneNumber, new_phoneNumber);

				printf("The contact information was changed successfully.\n");
				printf("The new name of contact is-----------> %s\n", address_book.contact_person[search_position - 1].ContactName);
				printf("The new phone number of contact is---> %s\n", address_book.contact_person[search_position - 1].PhoneNumber);
				getchar();
			}
			else
			{
				Reminder("Please enter the correct name of the contact.");
			}
		}

		if (UnknowJudge(unknown) == isPhoneNumber)
		{
			if (AddressBook_searchNumber(address_book, unknown, search_position) == Success)
			{
				printf("Please input the new name of the contact:");
				fgets(new_name, sizeof(new_name), stdin);
				DeleteEnter(new_name);

				printf("Please input the new phone number of the contact:");
				fgets(new_phoneNumber, sizeof(new_phoneNumber), stdin);
				DeleteEnter(new_phoneNumber);

				strcpy_s(address_book.contact_person[search_position - 1].ContactName, new_name);
				strcpy_s(address_book.contact_person[search_position - 1].PhoneNumber, new_phoneNumber);

				printf("The contact information was changed successfully.\n");
				printf("The new name of contact is-----------> %s\n", address_book.contact_person[search_position - 1].ContactName);
				printf("The new phone number of contact is---> %s\n", address_book.contact_person[search_position - 1].PhoneNumber);
				getchar();
			}
			else
			{
				Reminder("Please enter the correct name of the contact.");
			}
		}
	}
}

void AddressBookInformation()
{
	int l;
	int i;

	system("cls");
	l = address_book.length;
	for (i = 0; i < l - 1; i++)
	{
		OutputContactInformation_1(address_book.contact_person[i]);
	}

	printf("Press enter to exit.");

	getchar();
}#include "main.h"

/*
作者:CmeHY
项目名称:通讯录管理系统

顺序表应用实例:通讯录管理
实现功能:
	1.增加联系人
	2.查找联系人
	3.删除联系人
	4.修改联系人信息
	5.显示所有联系人
*/
int main()
{
	int data_cache;

	timer = 0;
	AddressBook_Init(address_book);
	Test();

	while (1)
	{
		UserInterface();
		printf("Please input your choice:");
		scanf_s("%d", &user_selection);

		JudgeSelection(userInterface);
		ClearBuffer();
		switch (user_selection)
		{
		
		case searchContact:
		{
			SearchFunction();

			break;
		}

		case addContact:
		{
			InsertFunction();

			break;
		}

		case deleteContact:
		{
			DeleteFunction();

			break;
		}

		case changeContact:
		{
			ChangeFunction();

			break;
		}

		case addressBookInformation:
		{
			AddressBookInformation();

			break;
		}
		}
	}
}

ContactPerson e;
/* Test specified function. */
void Test()
{

	strcpy_s(address_book.contact_person[0].ContactName, "ZHY");
	strcpy_s(address_book.contact_person[0].PhoneNumber, "15245");
	address_book.length += 1;

	strcpy_s(e.ContactName, "小白");
	strcpy_s(e.PhoneNumber, "89477411548");
	AddressBook_Insert(address_book, 1, e);

	strcpy_s(e.ContactName, "小明");
	strcpy_s(e.PhoneNumber, "55417411548");
	AddressBook_Insert(address_book, 1, e);

	strcpy_s(e.ContactName, "小黑");
	strcpy_s(e.PhoneNumber, "514515541");
	AddressBook_Insert(address_book, 1, e);
}

/*Interface Function*/
void PutStr(const char* str,int length,int mode)
{
	int i;
	int j;

	j = strlen(str);

	if (mode == 1)
	{
		for (i = 0; i < length; i++)
		{
			printf("%s", str);
		}

		printf("\n");
	}
	
	if (mode == 0)
	{
		printf("*");

		for (i = 1; i < ((length - j) / 2); i++)
		{
			printf(" ");
		}

		printf("%s", str);

		for (i = 1; i < ((length - j) / 2); i++)
		{
			printf(" ");
		}

		printf("*\n");
	}
}

void UserInterface()
{
	system("cls");

	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("1.Search a contact. ",80,0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("2.  Add a contact.  ", 80, 0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("3.Delete a contact. ", 80, 0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("4.Change a contact. ", 80, 0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("5.Open the address book.  ", 80, 0);
	PutStr(" ", 80, 1);
	PutStr("*", 80, 1);
}

void SearchInterface()
{
	system("cls");

	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("1.According to the name.  ", 80, 0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("2.According to the phone number.  ", 80, 0);
	PutStr(" ", 80, 1);
	PutStr("*", 80, 1);
}

void AddInterface()
{
	system("cls");

	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("1.Insert at the specified position. ", 80, 0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("2.Insert at the default position.   ", 80, 0);
	PutStr(" ", 80, 1);
	PutStr("*", 80, 1);
}

void DeleteInterface()
{
	system("cls");

	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("1.According to the name.  ", 80, 0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("2.According to the phone number.  ", 80, 0);
	PutStr(" ", 80, 1);
	PutStr("*", 80, 1);
}

void ChangeInterface()
{
	system("cls");

	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("1.Change the contact name.  ", 80, 0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("2.Change the contact phone number.  ", 80, 0);
	PutStr(" ", 80, 1);
	//
	PutStr("*", 80, 1);
	PutStr(" ", 80, 1);
	PutStr("3.Change the contact name and phone number.  ", 80, 0);
	PutStr(" ", 80, 1);
	PutStr("*", 80, 1);
}

void Reminder(const char* remind)
{
	system("cls");
	printf("------------------------%s------------------------\n",remind);
	
	printf("<<<------------------------Press enter to exit.------------------------>>>");
	getchar();
	return;
}

void JudgeSelection(functionInterface which_interface)
{
	switch (which_interface)
	{
	case userInterface:
	{
		if (user_selection < 1 || user_selection>5)
		{
			Reminder("Please enter the correct option.");
		}

		break;
	}

	case searchInterface:
	{
		if (search_selection < 1 || search_selection > 2)
		{
			Reminder("Please enter the correct option.");
		}

		break;
	}

	case deleteInterface:
	{
		if (delete_selection < 1 || delete_selection>2)
		{
			Reminder("Please enter the correct option.");
		}

		break;
	}

	case addInterface:
	{
		if (add_selection < 1 || add_selection>2)
		{
			Reminder("Please enter the correct option.");
		}

		break;
	}

	case changeInterface:
	{
		if (change_selection < 1 || change_selection > 3)
		{
			Reminder("Please enter the correct option.");
		}

		break;
	}

	default:
		break;
	}
}

int UnknowJudge(char* str)
{
	int i;
	int j;

	j = strlen(str);
	for (i = 0; i < j - 1; i++)
	{
		if (str[i] > '9') return isName;
	}

	return isPhoneNumber;
}

void ClearBuffer()
{
	int c;
	while ((c = getchar()) != '\n' && c != EOF) {}
}

void DeleteEnter(char* str)
{
	int i = 0;
	int j = strlen(str);
	while (i < j) {
		if (str[i] == '\n') {
			for (int k = i; k < j; k++) {
				str[k] = str[k + 1];
			}
			j--;
		}
		else {
			i++;
		}
	}
}

void OutputContactInformation(ContactPerson person)
{
	printf("--------------------------Contact Name------------------------->%s\n", person.ContactName);
	printf("--------------------------Phone Number------------------------->%s\n", person.PhoneNumber);
	printf("Press enter to exit.");
	getchar();
}

void OutputContactInformation_1(ContactPerson person_1)
{
	int k=100;

	printf("|   Contact Name >> %s\n", person_1.ContactName);
	printf("|   Phone Numbe  >> %s\n", person_1.PhoneNumber);

	while (k--)
	{
		printf("-");
	}

	printf("\n");
}

/*Application Function*/
void SearchFunction()
{
	SearchInterface();
	printf("Please input your choice:");
	scanf_s("%d", &search_selection);

	JudgeSelection(searchInterface);

	if (search_selection == according_to_name)
	{
		printf("Please enter the name of the contact:");

		ClearBuffer();		//清空输入的缓冲区
		fgets(input_name, sizeof(input_name), stdin); //stdin:标准输入
		DeleteEnter(input_name);			//删除回车键

		if (AddressBook_searchName(address_book, input_name, search_position) == Success)
		{
			AddressBook_getContact(address_book, search_position, information_cache);
			OutputContactInformation(information_cache);
		}
		else
		{
			Reminder("Please enter the correct name of the contact.");
		}
	}

	if (search_selection == according_to_phoneNumber)
	{
		printf("Please enter the phone number of the contact:");

		ClearBuffer();		//清空输入的缓冲区
		fgets(input_phoneNumber, sizeof(input_phoneNumber), stdin); //stdin:标准输入
		DeleteEnter(input_phoneNumber);			//删除回车键

		if (AddressBook_searchNumber(address_book, input_phoneNumber, search_position) == Success)
		{
			AddressBook_getContact(address_book, search_position, information_cache);
			OutputContactInformation(information_cache);
		}
		else
		{
			Reminder("Please enter the correct phone number of the contact.");
		}
	}
}

void InsertFunction()
{
	AddInterface();
	printf("Please input your choice:");
	scanf_s("%d", &add_selection);

	JudgeSelection(addInterface);
	if (add_selection == insert_specified_position)
	{
		printf("Please input the specified position:");
		scanf_s("%d", &add_position);

		printf("Please input the name of the contact:");
		ClearBuffer();
		fgets(input_name, sizeof(input_name), stdin);
		DeleteEnter(input_name);
		
		printf("Please input the phone number of the contact:");
		fgets(input_phoneNumber, sizeof(input_phoneNumber), stdin);
		DeleteEnter(input_phoneNumber);

		strcpy_s(information_cache.ContactName, input_name);
		strcpy_s(information_cache.PhoneNumber, input_phoneNumber);

		if (AddressBook_Insert(address_book, add_position, information_cache) == Success)
		{
			Reminder("The contact was added successfully and will be exited soon.");
		}
		else
		{
			Reminder("The contact addition failed.Please enter the correct position.");
		}

	}

	if (add_selection == insert_default_position)
	{
		printf("Please input the name of the contact:");
		ClearBuffer();
		fgets(input_name, sizeof(input_name), stdin);
		DeleteEnter(input_name);

		printf("Please input the phone number of the contact:");
		fgets(input_phoneNumber, sizeof(input_phoneNumber), stdin);
		DeleteEnter(input_phoneNumber);

		strcpy_s(information_cache.ContactName, input_name);
		strcpy_s(information_cache.PhoneNumber, input_phoneNumber);

		if (AddressBook_Insert(address_book, address_book.length, information_cache) == Success)
		{
			Reminder("The contact was added successfully and will be exit soon.");
		}
		else
		{
			Reminder("The contact addition failed.");
		}
	}
}

void DeleteFunction()
{
	DeleteInterface();

	printf("Please input your choice:");
	scanf_s("%d", &delete_selection);

	JudgeSelection(deleteInterface);

	if (delete_selection == according_to_name)
	{
		printf("Please input the name of the contact:");
		ClearBuffer();
		fgets(input_name, sizeof(input_name), stdin);
		DeleteEnter(input_name);

		if (AddressBook_searchName(address_book, input_name, search_position) == Success)
		{
			AddressBook_Delete(address_book, search_position);
			printf("The contact was deleted successfully.Press any key to exit.");
			getchar();
		}
		else
		{
			Reminder("Please enter the correct name of the contact.");
		}
	}

	if (delete_selection == according_to_phoneNumber)
	{
		printf("Please input the phone number of the contact:");
		ClearBuffer();
		fgets(input_phoneNumber, sizeof(input_phoneNumber), stdin);
		DeleteEnter(input_phoneNumber);

		if (AddressBook_searchNumber(address_book, input_phoneNumber, search_position) == Success)
		{
			AddressBook_Delete(address_book, search_position);
			printf("The contact was deleted successfully.Press any key to exit.");
			getchar();
		}
		else
		{
			Reminder("Please enter the correct phone number of the contact.");
		}
	}
}

void ChangeFunction()
{
	ChangeInterface();

	printf("Please input your choice:");
	scanf_s("%d", &change_selection);

	JudgeSelection(changeInterface);
	if (change_selection == change_contact_name)
	{
		printf("Please input the old name of the contact:");
		ClearBuffer();
		fgets(old_name, sizeof(old_name), stdin);
		DeleteEnter(old_name);

		if (AddressBook_searchName(address_book, old_name, search_position) == Success)
		{
			printf("Please input the new name of the contact:");
			fgets(new_name, sizeof(new_name), stdin);
			DeleteEnter(new_name);

			strcpy_s(address_book.contact_person[search_position - 1].ContactName, new_name);
			printf("The contact name was changed successfully.\n");
			printf("The new name of contact is-------> %s\n", address_book.contact_person[search_position - 1].ContactName);
			printf("The phone number of contact is---> %s\n", address_book.contact_person[search_position - 1].PhoneNumber);
			getchar();
		}
		else
		{
			Reminder("Please enter the correct name of the contact.");
		}
	}

	if (change_selection == change_contact_phoneNumber)
	{
		printf("Please input the old phone number of the contact:");
		ClearBuffer();
		fgets(old_phoneNumber, sizeof(old_phoneNumber), stdin);
		DeleteEnter(old_phoneNumber);

		if (AddressBook_searchNumber(address_book, old_phoneNumber, search_position) == Success)
		{
			printf("Please input the new phone number of the contact:");
			fgets(new_phoneNumber, sizeof(new_phoneNumber), stdin);
			DeleteEnter(new_phoneNumber);

			strcpy_s(address_book.contact_person[search_position - 1].PhoneNumber, new_phoneNumber);
			printf("The contact phone number was changed successfully.\n");
			printf("The contact name is-------> %s\n", address_book.contact_person[search_position - 1].ContactName);
			printf("The new phone number is---> %s\n", address_book.contact_person[search_position - 1].PhoneNumber);
			getchar();
		}
		else
		{
			Reminder("Please enter the correct name of the contact.");
		}
	}

	if (change_selection == change_contact_nameAndNumber)
	{
		printf("Please input the old phone number or old name of the contact:");
		ClearBuffer();
		fgets(unknown, sizeof(unknown), stdin);
		DeleteEnter(unknown);

		if (UnknowJudge(unknown) == isName)
		{
			if (AddressBook_searchName(address_book, unknown, search_position) == Success)
			{
				printf("Please input the new name of the contact:");
				fgets(new_name, sizeof(new_name), stdin);
				DeleteEnter(new_name);

				printf("Please input the new phone number of the contact:");
				fgets(new_phoneNumber, sizeof(new_phoneNumber), stdin);
				DeleteEnter(new_phoneNumber);

				strcpy_s(address_book.contact_person[search_position - 1].ContactName, new_name);
				strcpy_s(address_book.contact_person[search_position - 1].PhoneNumber, new_phoneNumber);

				printf("The contact information was changed successfully.\n");
				printf("The new name of contact is-----------> %s\n", address_book.contact_person[search_position - 1].ContactName);
				printf("The new phone number of contact is---> %s\n", address_book.contact_person[search_position - 1].PhoneNumber);
				getchar();
			}
			else
			{
				Reminder("Please enter the correct name of the contact.");
			}
		}

		if (UnknowJudge(unknown) == isPhoneNumber)
		{
			if (AddressBook_searchNumber(address_book, unknown, search_position) == Success)
			{
				printf("Please input the new name of the contact:");
				fgets(new_name, sizeof(new_name), stdin);
				DeleteEnter(new_name);

				printf("Please input the new phone number of the contact:");
				fgets(new_phoneNumber, sizeof(new_phoneNumber), stdin);
				DeleteEnter(new_phoneNumber);

				strcpy_s(address_book.contact_person[search_position - 1].ContactName, new_name);
				strcpy_s(address_book.contact_person[search_position - 1].PhoneNumber, new_phoneNumber);

				printf("The contact information was changed successfully.\n");
				printf("The new name of contact is-----------> %s\n", address_book.contact_person[search_position - 1].ContactName);
				printf("The new phone number of contact is---> %s\n", address_book.contact_person[search_position - 1].PhoneNumber);
				getchar();
			}
			else
			{
				Reminder("Please enter the correct name of the contact.");
			}
		}
	}
}

void AddressBookInformation()
{
	int l;
	int i;

	system("cls");
	l = address_book.length;
	for (i = 0; i < l - 1; i++)
	{
		OutputContactInformation_1(address_book.contact_person[i]);
	}

	printf("Press enter to exit.");

	getchar();
}

程序展示

通讯录管理系统

源代码文件

链接:https://pan.quark.cn/s/222a11e35119
提取码:uiqa

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值