数据结构 - 顺序表实现通讯录

test.c文件

#define _CRT_SECURE_NO_WARNINGS 1

#include "Contact.h"
int main() 
{
    Con myContacts;
    ConInit(&myContacts);
    int choice;
    int index;
    char targetName[100];
    PerInfo contact; // 创建一个新的联系人信息实例
    while (1) 
    {
        printf("\n--- 通讯录管理系统 ---\n");
        printf("1. 添加联系人到末尾\n");
        printf("2. 添加联系人到开头\n");
        printf("3. 删除最后一个联系人\n");
        printf("4. 删除第一个联系人\n");
        printf("5. 显示所有联系人信息\n");
        printf("6. 保存通讯录到文件\n");
        printf("7. 从文件加载通讯录\n");
        printf("8. 修改指定联系人的信息\n");
        printf("9. 查找指定联系人的信息\n");
        printf("10. 退出\n");
        printf("请选择一个操作:");
        int result = scanf("%d", &choice);
        if (result == 1) 
        {
            switch (choice)
            {
            case 1:
            {
                PerInfo newContact;
                printf("输入姓名:");
                scanf("%s", newContact.name);
                printf("输入性别:");
                scanf("%s", newContact.gender);
                printf("输入年龄:");
                scanf("%d", &newContact.age);
                printf("输入电话:");
                scanf("%s", newContact.telephone);
                printf("输入地址:");
                scanf("%s", newContact.address);
                ConPushBack(&myContacts, newContact);
                break;
            }
            case 2:
            {
                PerInfo newContact;
                printf("输入姓名:");
                scanf("%s", newContact.name);
                printf("输入性别:");
                scanf("%s", newContact.gender);
                printf("输入年龄:");
                scanf("%d", &newContact.age);
                printf("输入电话:");
                scanf("%s", newContact.telephone);
                printf("输入地址:");
                scanf("%s", newContact.address);
                ConPushFront(&myContacts, newContact);
                break;
            }
            case 3:
                ConPopBack(&myContacts);
                break;
            case 4:
                ConPopFront(&myContacts);
                break;
            case 5:
                ConDisplayAll(&myContacts);
                break;
            case 6:
                ConSave(&myContacts, "contacts.csv");
                break;
            case 7:
                ConLoad(&myContacts, "contacts.csv");
                break;
            case 8:
                printf("请输入要修改的联系人索引:");
                scanf("%d", &index);
                // 此处你需要一种方法来获取新的联系人信息
                // 可以是一个函数,或者直接在这里收集
                printf("输入新的姓名:");
                scanf("%s", contact.name);
                printf("输入新的性别:");
                scanf("%s", contact.gender);
                printf("输入新的年龄:");
                scanf("%d", &contact.age);
                printf("输入新的电话:");
                scanf("%s", contact.telephone);
                printf("输入新的地址:");
                scanf("%s", contact.address);
                // 在修改之前确保索引是有效的
                if (index >= 0 && index < myContacts.size) {
                    ConModify(&myContacts, index, contact);
                }
                else {
                    printf("无效的索引。\n");
                }
                break;
            case 9:
                printf("请输入要查找的联系人姓名:");
                scanf("%s", targetName);
                ConSearch(&myContacts, targetName);

                break;
            case 10:
                ConDestroy(&myContacts);
                printf("退出程序。\n");
                return 0;
            default:
                printf("无效选项,请重新选择。\n");
            }
        }
        else
        {
            // 读取失败,清理输入流
            while (getchar() != '\n'); // 读取并丢弃直到一个新行
            printf("输入无效,请输入一个数字。\n");
        }

    }
    return 0;
}

contact.c文件

#define _CRT_SECURE_NO_WARNINGS 1
#include "Contact.h"
//通讯录的初始化
void ConInit(Con* ps)
{
	assert(ps);
	ps->arr = NULL;
	ps->size = 0;
	ps->capacity = 0;
}

//通讯录的扩容
void ConCheckcapacity(Con* ps)
{
	if (ps->size == ps->capacity)
	{
		assert(ps);
		int newcapacity = ps->capacity == 0 ? INIT_CAPACITY : ps->capacity * 2;
		PerInfo* temp = (PerInfo*)realloc(ps->arr, newcapacity * sizeof(PerInfo));
		if (temp == NULL)
		{
			perror("realloc:");
			exit(1);
		}
		else
		{
			ps->arr = temp;
			ps->capacity = newcapacity;
		}
	}
}

//通讯录的销毁
void ConDestroy(Con* ps)
{
	assert(ps);
	free(ps->arr);
	ps->arr = NULL;
	ps->capacity = 0;
	ps->size = 0;
}

//添加联系人信息到第一个位置
void ConPushFront(Con* ps, PerInfo newContact)
{
	assert(ps);
	ConCheckcapacity(ps);
	for (int i = ps->size - 1;i >= 0;i--)
	{
		ps->arr[i + 1] = ps->arr[i];
	}
	ps->arr[0] = newContact;
	ps->size++;
}

//添加联系人信息到最后一个位置
void ConPushBack(Con* ps, PerInfo newContact)
{
	assert(ps);
	ConCheckcapacity(ps);
	ps->arr[ps->size] = newContact;
	ps->size++;
}

//删除第一个联系人信息
void ConPopFront(Con* ps)
{
	assert(ps);
	if (ps->size == 0) 
	{
		printf("提示:这个联系人列表是空的,没有东西可以删除\n");
		return;
	}
	else
	{
		for (int i = 0;i < ps->size - 1; i++)
		{
			ps->arr[i] = ps->arr[i + 1];
		}
		ps->size--;
	}
	printf("提示:第一个联系人删除成功\n");
}


//删除最后一个联系人信息
void ConPopBack(Con* ps)
{
	assert(ps);  // 确保通讯录指针不为空
	if (ps->size == 0) {
		printf("提示:通讯录为空,没有可以删除的联系人\n");
		return;
	}

	ps->size--;  // 减少通讯录的大小,移除最后一个元素
	printf("提示:最后一个联系人已成功删除\n");
}

//修改指定联系人的信息
void ConModify(Con* ps, int index, PerInfo updatedContact)
{
	assert(ps);
	if (index < 0 || index >= ps->size) {
		printf("输入的索引无效,无法修改联系人信息。\n");
		return;
	}
	// 更新指定索引处的联系人信息
	ps->arr[index] = updatedContact;
	//将新的联系人信息 updatedContact 赋值给 arr 数组的第 index 个位置。这个操作实质上是一个结构体赋值操作,它将 updatedContact 结构体的所有成员(包括姓名、性别、年龄、电话号码和地址等)复制到 arr[index] 所指向的结构体中。这意味着原来存储在该索引位置的联系人信息会被完全替换为新提供的信息。
	printf("联系人信息已成功更新:%s %s %d %s %s\n", updatedContact.name, updatedContact.gender, updatedContact.age, updatedContact.telephone, updatedContact.address);
}


//查找指定联系人的信息
void ConSearch(Con* ps, const char* targetName)
{
	assert(ps);  // 确保通讯录指针不为空
	int found = 0;  // 用于记录是否找到联系人

	for (int i = 0; i < ps->size; i++) {
		if (strcmp(ps->arr[i].name, targetName) == 0) {
			printf("找到联系人: 姓名:%s, 性别:%s, 年龄:%d, 电话:%s, 地址:%s\n",
				ps->arr[i].name, ps->arr[i].gender, ps->arr[i].age,
				ps->arr[i].telephone, ps->arr[i].address);
			found = 1;  // 标记为找到
		}
	}

	if (!found) {
		printf("未找到联系人:%s\n", targetName);
	}
}


// 打印所有联系人信息
void ConDisplayAll(Con * ps)
{
	assert(ps);  // 确保通讯录指针不为空
	if (ps->size == 0) {
		printf("通讯录为空,没有联系人信息可显示。\n");
		return;
	}

	printf("通讯录包含以下联系人:\n");
	for (int i = 0; i < ps->size; i++) {
		printf("%d. 姓名:%s, 性别:%s, 年龄:%d, 电话:%s, 地址:%s\n",
			i + 1,
			ps->arr[i].name,
			ps->arr[i].gender,
			ps->arr[i].age,
			ps->arr[i].telephone,
			ps->arr[i].address);
	}
}

// 保存所有联系人信息到文件
void ConSave(Con* ps, const char* filename)
{
	assert(ps);  // 确保通讯录指针不为空
	FILE* file = fopen(filename, "w");  // 打开文件用于写入
	if (file == NULL) {
		perror("无法打开文件");
		return;
	}

	// 写入通讯录大小,可用于加载数据
	fprintf(file, "%d\n", ps->size);
	for (int i = 0; i < ps->size; i++) {
		fprintf(file, "%s,%s,%d,%s,%s\n",
			ps->arr[i].name,
			ps->arr[i].gender,
			ps->arr[i].age,
			ps->arr[i].telephone,
			ps->arr[i].address);
	}

	fclose(file);  // 关闭文件
	printf("通讯录已成功保存到文件:%s\n", filename);
}

// 加载通讯录数据
void ConLoad(Con* ps, const char* filename)
{
	assert(ps);
	FILE* file = fopen(filename, "r");
	if (file == NULL) {
		perror("无法打开文件");
		return;
	}

	int size;
	fscanf(file, "%d\n", &size);  // 读取通讯录大小
	for (int i = 0; i < size; i++) {
		PerInfo info;
		fscanf(file, "%[^,],%[^,],%d,%[^,],%[^\n]\n",
			info.name,
			info.gender,
			&info.age,
			info.telephone,
			info.address);
		ConPushBack(ps, info);  // 将读取的信息添加到通讯录
	}

	fclose(file);
	printf("通讯录数据已从文件:%s 加载完成\n", filename);
}

contact.h文件

#pragma once

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

#define NAME_MAX 100
#define SEX_MAX 4
#define TEL_MAX 12
#define ADDR_MAX 100
#define INIT_CAPACITY 4

typedef struct PersonInfo {
    char name[NAME_MAX];
    char gender[SEX_MAX];
    int age;
    char telephone[TEL_MAX];
    char address[ADDR_MAX];
} PerInfo;

typedef struct Contact {
    PerInfo* arr;
    int size;
    int capacity;
} Con;

// Function declarations
void ConInit(Con* ps);
void ConCheckcapacity(Con* ps);
void ConDestory(Con* ps);
void ConPushFront(Con* ps, PerInfo newContact);
void ConPushBack(Con* ps, PerInfo newContact);
void ConPopFront(Con* ps);
void ConPopBack(Con* ps);
void ConModify(Con* ps, int index, PerInfo updatedContact);
void ConSearch(Con* ps, const char* targetName);
void ConDisplayAll(Con* ps);
void ConSave(Con* ps, const char* filename);
void ConLoad(Con* ps, const char* filename);

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值