单链表实现通讯录

目录

Contact.c

Contact.h

SList.c

SList.h

test.c


实现的代码在下面,接下来的一段在发疯,建议跳过,,,

啊啊啊啊啊啊,,,不是很复杂的代码写了又改改了好几天,其他的部分都挺一气呵成的,就是从文件中读取数据怎么读都是乱码,实在搞不定去请教了老师,也是万万没想到,和代码关系不大,编码格式的问题,,,,(阴暗)(扭曲地爬行)

Contact.c

#include "SList.h"
//从文件中导入原数据
/*使用文件的时候可能会出现由于记事本和集成开发环境的编码格式不同导致出现乱码,
这时把记事本的编码格式改成ANSI就好了,
改完依旧是乱码也不要紧,那不好几种编码格式嘛,多试一下,总会有一款适合你的编译器~*/
void LoadContact(contact** con)
{
	FILE* pf = fopen("contact.txt", "rb");
	if (pf == NULL)
	{ 
		perror("fopen");
		return;
	}
	PeoInfo info = { 0 };
	while (!feof(pf))
	{
		fscanf(pf, "%s %s %d %s %s\n", info.name, info.sex, &(info.age), info.tel, info.addr);
		SLTPushBack(con, info);
	}
	printf("历史数据导入成功!\n");
	fclose(pf);
	pf = NULL;
}
//初始化通讯录
void InitContact(contact** con)
{
	assert(con);
	(*con) = NULL;
	LoadContact(con);
}
//添加通讯录数据
void AddContact(contact** con)
{
	assert(con);
	PeoInfo info = { 0 };
	printf("请输入要添加的联系人姓名:\n");
	scanf("%s", info.name);
	printf("请输入要添加的联系人性别:\n");
	scanf("%s", info.sex);
	printf("请输入要添加的联系人年龄:\n");
	scanf("%d", &(info.age));
	printf("请输入要添加的联系人电话:\n");
	scanf("%s", info.tel);
	printf("请输入要添加的联系人住址:\n");
	scanf("%s", info.addr);
	SLTPushBack(con, info);
	printf("\n");
}
//根据联系人的姓名查找联系人
contact *FindByName(contact* con, char name[])
{
	assert(con);
	contact* cur = con;
	while (cur)
	{
		if (strcmp(cur->data.name, name) == 0)
		{
			return cur;
		}
		cur=cur->next;
	}
	return NULL;
}
//(根据联系人姓名)删除通讯录数据
void DelContact(contact** con)
{
	assert(con && (*con));
	char name[NAME_MAX];
	printf("请输入你要删除的联系人的名字:");
	scanf("%s", name);
	contact* ret = FindByName(*con, name);
	if (ret!=NULL)
	{
		SLTErase(con, ret);
		printf("删除成功!\n");
	}
	else
	{
		printf("该联系人数据不存在!\n");
		return;
	}
}
//展示通讯录数据
void ShowContact(contact* con)
{
	assert(con);
	contact* cur = con;
	printf("姓名\t\t性别\t\t年龄\t\t电话\t\t\t住址\n");
	while (cur)
	{
		printf("%s\t\t%s\t\t%d\t\t%s\t\t%s\n",
			cur->data.name,
			cur->data.sex,
			cur->data.age,
			cur->data.tel,
			cur->data.addr);
		cur = cur->next;
		printf("\n");
	}
}
//查找通讯录数据
void FindContact(contact* con)
{
	assert(con);
	char name[NAME_MAX];
	printf("请输入你要查找的联系人的名字:\n");
	scanf("%s", name);
	contact* ret = FindByName(con, name);
	if (ret == NULL)
	{
		printf("您要查找的联系人不存在!\n");
		return;
	}
	else
	{
		printf("姓名\t\t性别\t\t年龄\t\t电话\t\t\t住址\n");
		printf("%s\t\t%s\t\t%d\t\t%s\t\t%s\n",
			ret->data.name,
			ret->data.sex,
			ret->data.age,
			ret->data.tel,
			ret->data.addr);
		printf("\n");
	}
}
//修改通讯录数据
void ModifyContact(contact** con)
{
	assert(con);
	char name[NAME_MAX];
	printf("请输入你要修改的联系人的名字:\n");
	scanf("%s", name);
	contact* ret = FindByName(*con, name);
	if (ret == NULL)
	{
		printf("您要修改的联系人不存在!\n");
		return;
	}
	else
	{
		PeoInfo info = { 0 };
		printf("请输入修改后的联系人姓名:\n");
		scanf("%s", info.name);
		printf("请输入修改后的联系人性别:\n");
		scanf("%s", info.sex);
		printf("请输入修改后的联系人年龄:\n");
		scanf("%d", &(info.age));
		printf("请输入修改后的联系人电话:\n");
		scanf("%s", info.tel);
		printf("请输入修改后的联系人住址:\n");
		scanf("%s", info.addr);
		SLTModify(ret, info);
		printf("修改成功!\n");
	}
}
//将输入的数据保存到文件中
/*文件保存的时候又发现编译器这边的格式和记事本还是有冲突,数据存完之后又出了乱码,,,
感兴趣可以搜一下编码格式相关的内容(一个参考:https://www.zhihu.com/question/20650946)
大概还是可以解决的,
博主比较懒,这段代码就先不用了(代码本身是没有问题的)*/
//void SaveContact(contact** con)
//{
//	FILE* pf = fopen("contact.txt", "wb");
//	if (pf == NULL)
//	{
//		perror("fopen");
//		return;
//	}
//	contact* cur = *con;
//	while (cur)
//	{
//		fwrite(&(cur->data), sizeof(PeoInfo), 1, pf);
//		cur = cur->next;
//	}
//	printf("历史数据保存成功!\n");
//	fclose(pf);
//	pf = NULL;
//}
//销毁通讯录数据
void DestroyContact(contact** con)
{
	//SaveContact(con);
	SListDesTory(con);
}

Contact.h

#define _CRT_SECURE_NO_WARNINGS
#pragma once
#define NAME_MAX 100
#define SEX_MAX 4
#define TEL_MAX 12//为什么不是11呢,你试一下就知道了[手动狗头]
#define ADDR_MAX 100

//用户数据
typedef struct PersonInfo
{
    char name[NAME_MAX];
    char sex[SEX_MAX];
    int age;
    char tel[TEL_MAX];
    char addr[ADDR_MAX];
}PeoInfo;
typedef struct SListNode contact;

//初始化通讯录
void InitContact(contact** con);
//添加通讯录数据
void AddContact(contact** con);
//删除通讯录数据
void DelContact(contact** con);
//展示通讯录数据
void ShowContact(contact* con);
//查找通讯录数据
void FindContact(contact* con);
//修改通讯录数据
void ModifyContact(contact** con);
//销毁通讯录数据
void DestroyContact(contact** con);

SList.c

#include "SList.h"
//打印链表数据
//void SLTPrint(SLTNode* phead)
//{
//	SLTNode* pcur = phead;
//	while (pcur != NULL)
//	{
//		printf("%d->", pcur->data);
//		pcur = pcur->next;
//	}
//	printf("NULL\n");
//}
SLTNode* SLTBuyNode(SLTDataType x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	if (newnode == NULL)
	{
		perror("malloc");
		exit(1);
	}
	newnode->data = x;
	newnode->next = NULL;
	return newnode;
}
//链表的头插
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{
	assert(pphead);
	SLTNode* newnode = SLTBuyNode(x);
	newnode->next = *pphead;
	*pphead = newnode;
}
//链表的尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
	assert(pphead);
	SLTNode* newnode = SLTBuyNode(x);
	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{
		SLTNode* ptail = *pphead;
		while (ptail->next != NULL)
		{
			ptail = ptail->next;
		}
		ptail->next = newnode;
	}
}
//链表的头删
void SLTPopFront(SLTNode** pphead)
{
	assert(pphead && *pphead);
	SLTNode* next = (*pphead)->next;
	free(*pphead);
	*pphead = next;
}
//链表的尾删
void SLTPopBack(SLTNode** pphead)
{
	assert(pphead && *pphead);
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	else
	{
		SLTNode* prev = *pphead;
		SLTNode* ptail = *pphead;
		while (ptail->next)
		{
			prev = ptail;
			ptail = ptail->next;
		}
		free(ptail);
		ptail = NULL;
		prev->next = NULL;
	}
}
//查找
//SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
//{
//	SLTNode* pcur = phead;
//	while (pcur)
//	{
//		if (pcur->data == x)
//		{
//			return pcur;
//		}
//		pcur = pcur->next;
//	}
//	return NULL;
//}
//在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
	assert(pphead && *pphead);
	assert(pos);
	SLTNode* newnode = SLTBuyNode(x);
	if (pos == *pphead)
	{
		SLTPushFront(pphead, x);
	}
	else
	{
		SLTNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		newnode->next = pos;
		prev->next = newnode;
	}
}
//在指定位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{
	assert(pos);
	SLTNode* newnode = SLTBuyNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}
//删除pos节点
void SLTErase(SLTNode** pphead, SLTNode* pos)
{
	assert(pphead && *pphead);
	assert(pos);
	if (pos == *pphead)
	{
		SLTPopFront(pphead);
	}
	else
	{
		SLTNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;
		free(pos);
		pos = NULL;
	}
}
//删除pos之后的节点
void SLTEraseAfter(SLTNode* pos)
{
	assert(pos);
	SLTNode* del = pos->next;
	pos->next = del->next;
	free(del);
	del = NULL;
}
//修改pos节点的数据
void SLTModify(SLTNode* pos, SLTDataType x)
{
	assert(pos);
	pos->data = x;
}
//销毁链表
void SListDesTory(SLTNode** pphead)
{
	assert(pphead && *pphead);
	SLTNode* pcur = *pphead;
	while (pcur)
	{
		SLTNode* next = pcur->next;
		free(pcur);
		pcur = next;
	}
	*pphead = NULL;
}

SList.h

#define _CRT_SECURE_NO_WARNINGS
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "Contact.h"
typedef PeoInfo SLTDataType;

typedef struct SListNode
{
	SLTDataType data;
	struct SListNode* next;
}SLTNode;


//打印链表数据
//void SLTPrint(SLTNode* phead);

//链表的头插
void SLTPushFront(SLTNode** pphead, SLTDataType x);
//链表的尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x);
//链表的头删
void SLTPopFront(SLTNode** pphead);
//链表的尾删
void SLTPopBack(SLTNode** pphead);

//查找
//SLTNode* SLTFind(SLTNode* phead, SLTDataType x);
//在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);
//在指定位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x);

//删除pos节点
void SLTErase(SLTNode** pphead, SLTNode* pos);
//删除pos之后的节点
void SLTEraseAfter(SLTNode* pos);
//修改pos节点的数据
void SLTModify(SLTNode* pos, SLTDataType x);
//销毁链表
void SListDesTory(SLTNode** pphead);

test.c

#include "SList.h"
void menu()
{
	printf("————————————————通讯录————————————————\n");
	printf("*****1.增加联系人     2.删除联系人*****\n");
	printf("*****3.修改联系人     4.查找联系人*****\n");
	printf("*****5.展示联系人     0.退出      *****\n");
	printf("——————————————————————————————————————\n");
}
int main()
{
	int a = 0;
	contact* con = NULL;
    InitContact(&con);
	do
	{
		menu();
		printf("请选择您的操作:\n");
		scanf("%d", &a);
		switch (a)
		{
		case 1:
			AddContact(&con);
			break;
		case 2:
			DelContact(&con);
			break;
		case 3:
			ModifyContact(&con);
			break;
		case 4:
			FindContact(con);
			break;
		case 5:
			ShowContact(con);
			break;
		case 0:
			printf("退出通讯录。。。\n");
            DestoryContact(&con);
			break;
		default:
			printf("输入错误,请重新选择!\n");
			break;
		}
	} while (a != 0);
	DestroyContact(&con);
	return 0;
}

暂时就这样,等哪天我学会了如何彻底解决编码格式问题再回来改,拜拜了您内~

  • 15
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值