#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_SIZE 200
typedef struct person
{
char name[20];
char pnumber[20];
struct person* next;
}Person;
typedef struct Contacts
{
Person* T;
int count;
}Contacts;
struct PinYinMapping
{
char hanzi[4];
char pinyin;
};
struct PinYinMapping pinyinMapping[MAX_SIZE] = {
{"王",'W'},{"李",'L'},{"张",'Z'},{"刘",'L'},
{"陈",'C'},{"杨",'Y'},{"黄",'H'},{"赵",'Z'},
{"周",'Z'},{"胡",'H'},{"吴",'W'},{"徐",'X'},
{"朱",'Z'},{"高",'G'},{"孙",'S'},{"林",'L'},
{"马",'M'},{"郭",'G'},{"宋",'L'},{"曹",'C'},
{"何",'H'},{"江",'J'},{"邓",'D'},{"蒋",'J'},
{"罗",'L'}
};
void Menu();
void Add(Contacts* Phonebook);
int getFirstPinyin(const char* hanzi);
void Search(Contacts* Phonebook);
void Delete(Contacts* Phonebook);
void Modify(Contacts* Phonebook);
void DisplayPhonebook(Contacts* Phonebook);
void FreeNode(Contacts* Phonebook);
void saveContactstoPhonebook(Contacts* Phonebook);
void loadContactsfromPhonebook(Contacts* Phonebook);
int main(void)
{
Contacts* Phonebook = (Contacts*)malloc(sizeof(Contacts));
if (!Phonebook)
{
printf("出现错误,请推出重新进入。\n");
return -1;
}
Phonebook->T = (Person*)malloc(sizeof(Person) * 26);
Phonebook->count = 0;
for (int i = 0; i < 26; i++)
{
Phonebook->T[i].next = NULL;
}
loadContactsfromPhonebook(Phonebook);
Menu();
int key;
printf("1->增 2->删 3->改 4->查 5->Phonebook 6->保存联系人到文件\n");
printf("请输入操作(-1代表退出系统):");
scanf("%d", &key);
while (key != -1)
{
switch (key)
{
case 1:Add(Phonebook);
break;
case 2:Delete(Phonebook);
break;
case 3:Modify(Phonebook);
break;
case 4:Search(Phonebook);
break;
case 5:DisplayPhonebook(Phonebook);
break;
case 6:saveContactstoPhonebook(Phonebook);
break;
default:printf("ERROR!\n");
}
printf("1->增 2->删 3->改 4->查 5->Phonebook 6->保存联系人到文件\n");
printf("请再次输入操作(-1代表退出系统):");
scanf("%d", &key);
}
FreeNode(Phonebook);
free(Phonebook);
Phonebook = NULL;
printf("******************************************\n");
printf("******************************************\n");
return 0;
}
void Menu()
{
printf("******************************************\n");//length->39
printf("******************通讯录******************\n");
printf("************请选择要实现的功能************\n");
printf("1:添加联系人\n");
printf("2:删除联系人\n");
printf("3;修改联系人\n");
printf("4:查找联系人\n");
printf("5:展示所有联系人\n");
printf("6:保存联系人到文件\n");
printf("******************************************\n");
}
void Add(Contacts* Phonebook)
{
if (Phonebook->count >= MAX_SIZE)
{
printf("通讯录容量已满。\n");
return;
}
Person* newnode = (Person*)malloc(sizeof(Person));
printf("请输入联系人信息:\n");
printf("1、姓名:");
scanf("%s", newnode->name);
printf("2、电话号码:");
scanf("%s", newnode->pnumber);
int ret = getFirstPinyin(newnode->name);
if (ret == -1)
{
printf("请先退出并手动添加这个姓氏到pinyinMapping中,再重新添加此联系人\n非常感谢!!!\n");
return;
}
newnode->next = Phonebook->T[ret].next;
Phonebook->T[ret].next = newnode;
Phonebook->count++;
printf("添加成功!\n");
printf("------------------------------------------\n");
}
int getFirstPinyin(const char* hanzi) {
int i;
for (i = 0; i < sizeof(pinyinMapping) / sizeof(struct PinYinMapping); i++) {
if (strncmp(pinyinMapping[i].hanzi, hanzi,1) == 0) {
return (pinyinMapping[i].pinyin-'A');
}
}
return -1; // 如果映射表中没有找到对应的拼音首字母,则返回-1 表示未知
}
void Search(Contacts* Phonebook)
{
char name[20];
printf("请输入要查找的人:");
scanf("%s", name);
int ad = getFirstPinyin(name);
Person* p = &Phonebook->T[ad];
p = p->next;
while (p)
{
if (!strcmp(name, p->name))
{
printf("找到%s了。\n",p->name);
printf("%s的电话号码是:%s\n", p->name,p->pnumber);
return;
}
p = p->next;
}
if (!p)
printf("没有找到%s。\n",name);
printf("------------------------------------------\n");
}
void Delete(Contacts* Phonebook)
{
char src[20];
printf("请输入要删除的人:");
scanf("%s", src);
int ad = getFirstPinyin(src);
Person* p = &Phonebook->T[ad];
Person* q = p->next;
while (q)
{
if (!strcmp(q->name, src))
{
p->next = q->next;
free(q);
q = NULL;
printf("%s删除成功!\n",src);
Phonebook->count--;
return;
}
p = q;
q = q->next;
}
if (!q)
printf("通讯录中没有%s\n", src);
printf("------------------------------------------\n");
}
void Modify(Contacts* Phonebook)
{
char dest[20];
printf("请输入要修改的人:");
scanf("%s", dest);
int ad = getFirstPinyin(dest);
Person* p = &Phonebook->T[ad];
p = p->next;
while (p)
{
if (!strcmp(p->name, dest))
{
printf("选择要修改的内容:\n1 ->姓名\n2 ->电话号码\n");
int key;
scanf("%d", &key);
printf("请输入要修改的内容:");
switch (key)
{
case 1:scanf("%s", p->name);
break;
case 2:scanf("%s", p->pnumber);
break;
default:printf("Error!\n");
}
printf("修改成功!\n");
return;
}
p = p->next;
}
if (!p)
printf("通讯录没有%s", dest);
printf("------------------------------------------\n");
}
void DisplayPhonebook(Contacts* Phonebook)
{
if (Phonebook->count == 0)
{
printf("通讯录为空!\n");
return;
printf("------------------------------------------\n");
}
printf("******************通讯录******************\n");
char ch = 'A';
for (int i = 0; i < 26; i++)
{
Person* p = &Phonebook->T[i];
p = p->next;
printf("%c\n联系人姓名\t电话号码\n",ch+i);
while (p)
{
printf("%s\t\t%s\n", p->name, p->pnumber);
p = p->next;
}
}
}
void saveContactstoPhonebook(Contacts* Phonebook)
{
FILE* fp = fopen("PhoneBook.txt", "w");
if (!fp)
{
printf("Failed to open file!\n");
return;
}
for (int i = 0; i < 26; i++)
{
Person* p = (Phonebook->T)+i;
p = p->next;
while (p)
{
fprintf(fp, "%s;%s\n", p->name, p->pnumber);
p = p->next;
}
}
fclose(fp);
printf("联系人已保存到文件中。\n");
printf("------------------------------------------\n");
}
void loadContactsfromPhonebook(Contacts* Phonebook)
{
FILE* fp = fopen("PhoneBook.txt", "r");
if (!fp)
{
printf("Failed to open file: PhoneBook.txt\n");
perror("Error");
return;
}
while (!feof(fp) && Phonebook->count < MAX_SIZE)
{
Person* newnode = (Person*)malloc(sizeof(Person));
fscanf(fp, "%[^;];%[^\n]\n", newnode->name, newnode->pnumber);
int ret = getFirstPinyin(newnode->name);
newnode->next = Phonebook->T[ret].next;
Phonebook->T[ret].next = newnode;
Phonebook->count++;
}
printf("已从文件加载了%d个联系人.\n", Phonebook->count);
fclose(fp);
printf("------------------------------------------\n");
}
void FreeNode(Contacts* Phonebook)
{
for (int i = 0; i < 26; i++)
{
Person* p = (Phonebook->T)[i].next;
while (p)
{
Person* s = p->next;
free(p);
p = s;
}
(Phonebook->T)[i].next = NULL; // 清空哈希槽
}
}
说实话我不理解我释放Phonebook->T指向的26个堆空间,为什么不行啊?奇怪的很,真的不理解呀!!!抽象。