Lenguaje C - libreta de direcciones detallada (versión dinámica)

Prefacio:

Ya hemos aprendido acerca de la versión estática de la libreta de direcciones, pero sus deficiencias son obvias: cuando la libreta de direcciones está llena, no se pueden agregar contactos. Actualizaré la libreta de direcciones nuevamente y escribiré una versión dinámica de la libreta de direcciones. ( Hipervínculo a la versión estática de la libreta de direcciones )
Objetivos de transformación:
1. El espacio de la libreta de direcciones no es fijo y el tamaño se puede ajustar.
2. De forma predeterminada, se puede almacenar la información de 3 personas. Si es no es suficiente, agregue más. Aquí agregaré 3 personas a la vez.

1. Definir una libreta de direcciones

//定义一个通讯录
typedef struct Comcation
{
    
    
    com *data;//可以存100个人的信息
    int sz;//记录存放人的位置
    int capacity;//记录容量
}contact;

La estructura agrega una capacidad de miembro de capacidad récord

2. Inicialización

La libreta de direcciones predeterminada puede contener la información de tres personas

void initCantact(contact* pc)
{
    
    
    assert(pc);
    pc->data = (com*)malloc(3*sizeof(com));
    if (pc->data == NULL)
    {
    
    
        perror("initCantact");
        return;
    }
    pc->sz = 0;
    pc->capacity = CONTACT_SZ;
}

Deja que la estructura se inicialice

3. Agregar contactos

3.1 Ampliar la libreta de direcciones

Debido a que la libreta de direcciones solo puede contener la información de tres personas, necesitamos expandir la libreta de direcciones

int Addcapacity(contact* pc)
{
    
    
    if (pc->sz == pc->capacity)//容量满了就增容
    {
    
    
        com* ptr = (com*)realloc(pc->data, (pc->capacity + INT_sz) * sizeof(com));
        if (ptr == NULL)
        {
    
    
            perror("Addcapacity");
            return 0;
        }
        else
        {
    
    
            pc->data = ptr;
            pc->capacity = pc->capacity + INT_sz;
            printf("增容成功\n");
            return 1;
        }
    }
    return 1;
}

Lo que se devuelve es un número entero, y luego juzgamos si la expansión falla en función del valor devuelto.

3.2 Agregar contactos

He definido dos macros más sobre la base de la libreta de direcciones estática, lo que
facilita mucho cambiar la capacidad inicial y el tamaño de un aumento de capacidad,
inserte la descripción de la imagen aquí
y luego puedo escribir la función de agregar contactos

//增加联系人
void Addcontact(contact* pc)
{
    
    
    assert(pc);
    int n = Addcapacity(pc);
        if(0==n ) //增容
        {
    
    
            //增容失败
            return;
        }
 
    printf("请输入名字:");
    scanf("%s", pc->data[pc->sz].name);
    printf("请输入年龄:");
    scanf("%d", &(pc->data[pc->sz].age));
    printf("请输入性别:");
    scanf("%s", pc->data[pc->sz].sex);
    printf("请输入电话号码:");
    scanf("%s", pc->data[pc->sz].tele);
    printf("请输入地址:");
    scanf("%s", pc->data[pc->sz].addr);
    pc->sz++;
    printf("成功增加联系人\n");
}

4. Liberar memoria

Debido a que la memoria que hemos asignado está en el montón, si no la liberamos manualmente, el espacio asignado siempre existirá y luego consumirá memoria (pérdida de memoria).
Para evitar que esto suceda, la memoria debe liberarse antes de que el programa salga.

//释放通讯录内存
void Destorycontacy(contact* pc)
{
    
    
    free(pc->data);
    pc->data = NULL;
    pc->sz = 0;
    pc->capacity = 0;
}

Cinco, código completo

Sobre la base de la versión estática, solo necesita cambiar el contenido anterior y se convertirá en una versión dinámica de la libreta de direcciones.
El código específico es el siguiente:
archivo de cabecera cantact.h (declaración y definición de función):

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#define MAX 100//可以增加的人数
#define NAME_MAX 20//姓名
#define SEX_MAX 5//性别
#define TELE_MAX 12//电话
#define ADDR_MAX 20//地址
#define CONTACT_SZ 3//初始容量
#define INT_sz 3//一次增容的大小
//定义一个结构体
typedef struct Communication
{
    
    
    char name[NAME_MAX];//姓名
    int age;//年龄
    char sex[SEX_MAX];//性别
    char tele[TELE_MAX];//电话
    char addr[ADDR_MAX];//地址
}com;
//定义一个通讯录
typedef struct Comcation
{
    
    
    com *data;//可以存100个人的信息
    int sz;//记录存放人的位置
    int capacity;//记录容量
}contact;
//给通讯录赋初值
void initCantact(contact* pc);
//增容函数
int Addcapacity(contact* pc);
//菜单
void menu(void);
//增加联系人
void Addcontact(contact* pc);
//显示联系人
void Showcontact(const contact* pc);
//删除联系人
void Delcontact(contact* pc);
//查找联系人
int Findcontact(contact* pc, char arr[20]);
//查找指定联系人
void Searchcontact(contact* pc);
//修改联系人
void Modfycontatc(contact* pc);
//联系人按名字进行排序
void Sortcontact(contact* pc);
//清空联系人
void Emptycontact(contact* pc);
//释放内存
void Destorycontacy(contact* pc);



archivo fuente cantact.c (implementación de la función):

#include "cantact.h"
//通讯录初始化
void initCantact(contact* pc)
{
    
    
    assert(pc);
    pc->data = (com*)malloc(3*sizeof(com));
    if (pc->data == NULL)
    {
    
    
        perror("initCantact");
        return;
    }
    pc->sz = 0;
    pc->capacity = CONTACT_SZ;
}
//增容函数
int Addcapacity(contact* pc)
{
    
    
    if (pc->sz == pc->capacity)//容量满了就增容
    {
    
    
        com* ptr = (com*)realloc(pc->data, (pc->capacity + INT_sz) * sizeof(com));
        if (ptr == NULL)
        {
    
    
            perror("Addcapacity");
            return 0;
        }
        else
        {
    
    
            pc->data = ptr;
            pc->capacity = pc->capacity + INT_sz;
            printf("增容成功\n");
            return 1;
        }
    }
    return 1;
}
//增加联系人
void Addcontact(contact* pc)
{
    
    
    assert(pc);
    int n = Addcapacity(pc);
        if(0==n ) //增容
        {
    
    
            //增容失败
            return;
        }
 
    printf("请输入名字:");
    scanf("%s", pc->data[pc->sz].name);
    printf("请输入年龄:");
    scanf("%d", &(pc->data[pc->sz].age));
    printf("请输入性别:");
    scanf("%s", pc->data[pc->sz].sex);
    printf("请输入电话号码:");
    scanf("%s", pc->data[pc->sz].tele);
    printf("请输入地址:");
    scanf("%s", pc->data[pc->sz].addr);
    pc->sz++;
    printf("成功增加联系人\n");
}
//显示联系人
void Showcontact(const contact* pc)
{
    
    
    assert(pc);
    printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n\n", "名字", "年龄", "性别", "电话", "地址");
    int i = 0;
    for (i = 0; i < pc->sz; i++)
    {
    
    
        printf("%-20s\t%-4d\t%-5s\t%-12s\t%-30s\n",
            pc->data[i].name,
            pc->data[i].age,
            pc->data[i].sex,
            pc->data[i].tele,
            pc->data[i].addr);
    }
}
//查找联系人
int Findcontact(contact* pc, char arr[20])
{
    
    
    int i = 0;

    for (i = 0; i < pc->sz; i++)
    {
    
    
        if (strcmp(pc->data[i].name, arr) == 0)//找到了
        {
    
    
            return i;
        }
    }
    return -1;//没找到
}
//删除联系人
void Delcontact(contact* pc)
{
    
    
    if (pc->sz == 0)
    {
    
    
        printf("没有联系人,无需删除\n");
        return;
    }
    char arr[20] = {
    
     0 };
    assert(pc);
    printf("请输入要删除的人的名字:");
    scanf("%s", arr);//名字
    int n;
    n = Findcontact(pc, arr);
    if (n == -1)
    {
    
    
        printf("没找到\n");
        return;
    }
    else//找到了
    {
    
    
        int i = 0;
        for (i = n; i < pc->sz - 1; i++)//从当前位置开始,把后面的值都往前面挪一位
        {
    
    
            pc->data[i] = pc->data[i + 1];
        }
        pc->sz--;
    }
    printf("成功删除联系人\n");
}
//查找指定联系人
void Searchcontact(contact* pc)
{
    
    
    assert(pc);
    char p[20] = {
    
     0 };
    printf("请输入要查找人的姓名:");
    scanf("%s", p);
    int n = Findcontact(pc, p);
    if (n == -1)
    {
    
    
        printf("要查找的人不存在\n");
    }
    else
    {
    
    
        printf("%-20s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
        //打印数据
        printf("%-20s\t%-4d\t%-5s\t%-12s\t%-30s\n",
            pc->data[n].name,
            pc->data[n].age,
            pc->data[n].sex,
            pc->data[n].tele,
            pc->data[n].addr);
    }
}
//修改联系人
void Modfycontatc(contact* pc)
{
    
    
    assert(pc);
    char name[20] = {
    
     0 };
    if (pc->sz == 0)
    {
    
    
        printf("没有联系人,无需修改\n");
        return;
    }
    printf("请输入要修改人的名字;");
    scanf("%s", name);
    int n = 0;
    n = Findcontact(pc, name);
    if (n == -1)
    {
    
    
        printf("要修改的人不存在\n");
    }
    else
    {
    
    
        printf("请输入修改后的名字:");
        scanf("%s", pc->data[n].name);
        printf("请输入修改后的年龄:");
        scanf("%d", &(pc->data[n].age));
        printf("请输入修改后的性别:");
        scanf("%s", pc->data[n].sex);
        printf("请输入修改后的电话号码:");
        scanf("%s", pc->data[n].tele);
        printf("请输入修改后的地址:");
        scanf("%s", pc->data[n].addr);
        printf("修改成功\n");
    }
}
int comper(const void* p1, const void* p2)//字符比较
{
    
    
    return strcmp(((com*)((contact*)p1)->data)->name, ((com*)((contact*)p2)->data)->name);
}
//按名字进行排序
void Sortcontact(contact* pc)
{
    
    
    qsort(pc, pc->sz, sizeof(pc->data[0]), comper);//快排
}
//清空联系人
void Emptycontact(contact* pc)
{
    
    
    assert(pc);
    if (pc->sz == 0)
    {
    
    
        printf("联系人为空,无需清空\n");
    }
    else
    {
    
    
        pc->sz = 0;
        printf("清空成功\n");
    }
}
//释放通讯录内存
void Destorycontacy(contact* pc)
{
    
    
    free(pc->data);
    pc->data = NULL;
    pc->sz = 0;
    pc->capacity = 0;
}

archivo fuente test.c (libreta de direcciones de prueba):

#include "cantact.h"
//菜单
void menu(void)
{
    
    
    printf("————————————————————\n");
    printf("|***************************************|\n");
    printf("|*****1.增加联系人     2.删除联系人*****|\n");
    printf("|*****3.修改联系人     4.查找联系人*****|\n");
    printf("|*****5.显示所有联系人 6.排序      *****|\n");
    printf("|*****7.清除所有联系人 0.退出程序   ****|\n");
    printf("|***************************************|\n");
    printf("————————————————————\n");
}
int main()
{
    
    
    int input = 0;
    //通讯录初始化
    contact pc;
    initCantact(&pc);
    do
    {
    
    
        menu();
        printf("请选择:\n");
        scanf("%d", &input);//
        switch (input)
        {
    
    
        case 1:
            Addcontact(&pc);//增加联系人
            break;
        case 2:
            Delcontact(&pc);//删除联系人
            break;
        case 3:
            Modfycontatc(&pc);//修改联系人
            break;
        case 4:
            Searchcontact(&pc);//查找指定联系人
            break;
        case 5:
            Showcontact(&pc);//显示联系人
            break;
        case 6:
            Sortcontact(&pc);//按名字进行排序
            break;
        case 7:
            //清空所以联系人
            Emptycontact(&pc);
            break;
        case 0:
            Destorycontacy(&pc);
            printf("退出程序\n");
            break;
        default:
            printf("输入错误,重新输入\n");
        }
    } while (input);
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/plj521/article/details/132253217
Recomendado
Clasificación