【C】通讯录(链表+文件存储)

12 篇文章 0 订阅
2 篇文章 0 订阅
/*****************************************************
copyright (C), 2014-2015, Lighting Studio. Co.,     Ltd. 
File name:
Author:Jerey_Jobs    Version:0.1    Date: 
Description:
Funcion List: 
*****************************************************/

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

void get_name(char*);
void get_num(char*,int);
void get_address(char*);
char get_check(char*);

struct node
{
    char name[20];
    char hometel[9];
    char phone[12];
    char address[100];

    struct node * next;
};

typedef struct node Node;
typedef struct node * Link;



void welcome()
{
    printf(" =============================================================================\n");
    printf("|                                                                             |\n");
    printf("|                                  通讯录                                     |\n");
    printf("|                                                                             |\n");
    printf(" =============================================================================\n");
    printf("|                                                                             |\n");
    printf("|              1 显示通讯录                   2 添加联系人信息                |\n");
    printf("|              3 删除联系人信息               4 查找联系人信息                |\n");
    printf("|              5 修改联系人信息               6 退出                          |\n");
    printf("|                                                                             |\n");
    printf(" =============================================================================\n");
    printf("\n");
    printf("请输入操作对应的数字:");
}

void create_node(Link *new_node)
{
    int count = 10;

    do
    {
        *new_node = (Link)malloc(sizeof(Node));
        count--;
    }while(!is_malloc_ok(*new_node) && count);
}

void create_link(Link *head)
{
    create_node(head);
    (*head)->next = NULL;
}

int is_malloc_ok(Link new_node)
{
    if(new_node == NULL)
    {
        printf("malloc error!\n");
        return 0;
    }
    return 1;
}

void insert_node_and_sort(Link head,Link new_node)
{
    Link p = head->next;
    Link q = head;

    if(p == NULL)
    {
        new_node->next = head->next;
        head->next = new_node;
    }
    else
    {                                                                                                                                                                                                                                                               
        while(p != NULL && strcmp(p->name,new_node->name) < 0)
        {
            q = p;
            p = p->next;
        }

        if(p == NULL)
        {
            new_node->next = p;
            q->next = new_node;
        }
        else
        {
            q->next = new_node;
            new_node->next = p;
        }
    }

}

void display(Link head)
{
    if(head == NULL)
    {
        printf("链表已经完全释放!\n");
        return;
    }

    Link p = head->next;

    if(p == NULL)
    {
        printf("通讯录为空!\n");
    }
    else
    {
        printf("\t联系人姓名\t座机号\t\t手机号\t\t家庭地址\n");
        printf("-------------------------------------------------------------\n");
        while(p != NULL)
        {
            printf("\t%s\t\t%s\t%s\t%s\n",p->name,p->hometel,p->phone,p->address);
            p = p->next;
        }
    }
}

void clear_screen()
{
    char str;

    printf("\n已成功执行,请按回车键继续操作\n");
    my_get(&str,1);
    system("clear");
    welcome();
}

void create_new_contact(Link head,Link *new_node)
{
    char str[2];
    
    do{

        create_node(new_node);
        printf("请输入新联系人的\n姓      名 :");
        get_name((*new_node)->name);
       // scanf("%s",(*new_node)->name);
        printf("座  机  号 :");
        get_num((*new_node)->hometel,9);
       // scanf("%s",(*new_node)->hometel);
        printf("手  机  号 :");
        get_num((*new_node)->phone,12);
       // scanf("%s",(*new_node)->phone);
        printf("家 庭 地 址:");
       // scanf("%s",(*new_node)->address);
        get_address((*new_node)->address);

        insert_node_and_sort(head,*new_node);

        printf("\n保存成功!是否要继续输入?(Y/N):");
        get_check(str);

        printf("\n");

    }while(strcmp(str,"Y") == 0);
    
}


void delete_contact(Link head)
{
    char str[20];
    char str1[2];

    do
    {
        printf("请输入你想删除的联系人的姓名:");
        //scanf("%s",str);
        get_name(str);

        //delete_node(head,str);

///
        Link p = head->next;
        Link q=head;
    
    
        while(p != NULL && strcmp(p->name,str) != 0)
        {
            q = p;
            p = p->next;
        }

        if(p == NULL)
        {
            printf("\n抱歉,未找到你想删除的联系人,请确认是否输入正确\n");
        }
        else
        {
            q->next = p->next;
            free(p);
        }

///

        printf("\n是否继续删除?(Y/N):");
        get_check(str1);
        printf("\n");
    }while(strcmp(str1,"Y") == 0);

}


void delete_node(Link head,char str[])
{
    Link p = head->next;
    Link q=head;
    
      
    while(p != NULL && strcmp(p->name,str) != 0)
    {
        q = p;
        p = p->next;
    }

    if(p == NULL)
    {
        printf("抱歉,未找到你想删除的联系人,请确认是否输入正确\n");
    }
    else
    {
        q->next = p->next;
        free(p);
        printf("删除成功!");
    }
}

void find_contact(Link head)
{
    char str[20];
    char str1[2];
    Link p = head->next;

    do{

    printf("请输入你想查找的联系人的姓名:");
    //scanf("%s",str);
    get_name(str);

    while(p != NULL && strcmp(str,p->name) != 0)
    {
        p = p->next;
    }

    if(p == NULL)
    {
        printf("抱歉,未找到你想查找的联系人,请确认输入是否正确\n");
    }
    else
    {
        printf("\n该联系人信息:\n");
        printf("姓      名 :%s\n",p->name);
        printf("座  机  号 :%s\n",p->hometel);
        printf("手  机  号 :%s\n",p->phone);
        printf("家 庭 地 址:%s\n",p->address);
    }
          printf("\n是否继续查询?(Y/N):");
          get_check(str1);
          printf("\n");
      }while(strcmp(str1,"Y") == 0);

}

void alter_contact(Link head)
{
    char str[20];
    char str1[50];
    char str2[2];
    char str3[2];
    int num;
    Link p =head->next;
    
    do
    {
        printf("1 按姓名修改      2 按座机号修改\n请输入选项: ");
        //scanf("%d",&num);
        num = get_mode(str3,2);

        switch(num)
        {
            case 1:
                printf("请输入你想修改的联系人的姓名:");
                //scanf("%s",str);
                get_name(str);

                while(p != NULL && strcmp(str,p->name) != 0)
                {
                    p = p->next;
                }
            
                if(p == NULL)
                {
                    printf("抱歉,未找到你想修改的联系人,请确认输入是否正确\n");
                }
                else
                {
                    printf("\n该联系人信息:\n");
                    printf("姓      名 :%s\n",p->name);
                    printf("座  机  号 :%s\n",p->hometel);
                    printf("手  机  号 :%s\n",p->phone);
                    printf("家 庭 地 址:%s\n",p->address);
                

                    printf("请修改:\n");
                    printf("请输入联系人的\n姓      名 :");
                    get_name(p->name);
                    printf("座  机  号 :");
                    get_num(p->hometel,9);
                    printf("手  机  号 :");
                    get_num(p->phone,12);
                    printf("家 庭 地 址:");
                    get_address(p->address);
                }
                break;

            case 2:
                printf("请输入你想修改的联系人的座机号:");
                get_num(str,9);

                while(p != NULL && strcmp(str,p->hometel) != 0)
                {
                    p = p->next;
                }
            
                if(p == NULL)
                {
                    printf("抱歉,未找到你想修改的联系人,请确认输入是否正确\n");
                }
                else
                {
                    printf("\n该联系人信息:\n");
                    printf("姓      名 :%s\n",p->name);
                    printf("座  机  号 :%s\n",p->hometel);
                    printf("手  机  号 :%s\n",p->phone);
                    printf("家 庭 地 址:%s\n",p->address);
                

                    printf("请修改:\n");
                    printf("请输入联系人的\n姓      名 :");
                    get_name(p->name);
                    printf("座  机  号 :");
                    get_num(p->hometel,9);
                    printf("手  机  号 :");
                    get_num(p->phone,12);
                    printf("家 庭 地 址:");
                    get_address(p->address);
                }
                break;

        }
            printf("\n是否继续修改?(Y/N):");
            get_check(str2);
            printf("\n");
   
    }while(strcmp(str2,"Y") == 0);
}

int my_get(char str[],int length)   //length为存放的最长长度
{
    int i;

    for(i = 0; i < length ; i++)
    {
        str[i] = getchar();
        if(str[i] == '\n')
        {
            str[i] = '\0';
            return i;
        }
    }

    while(getchar() != '\n');
    str[i - 1] = '\0';
    return -1;

}



int check_name(char *str)
{
    char *p = str;

    if(*p == '\0')          //不加的话,如果输入姓名直接打回车键它是会认为没有错的。
    {                       //因为my_get会把回车改为'\0',而姓名输入又不像数字输入一样有长度限制(就是确定的长度)
        return 0;
    }

    while(*p != '\0')
    {
        if(!((*p >= 'a' && *p <= 'z') || (*p >= 'A' &&*p <= 'Z')))
        {
            return 0;
        }
        p++;
    }

    return 1;
    
}

int check_num(char *str)
{
    char *p = str;

    while(*p != '\0')
    {
        if(!(*p >= '0' && *p <= '9'))
        {
            return 0;
        }
        p++;
    }

    return 1;
}

int check_mode(char *str,int num)
{
    if(*str >= '1' && *str <= '0'+num)
    {
        return 1;
    }
    
    return 0;
}

int check_check(char *str)
{
    if(*str == 'Y' || *str == 'N')
    {
        return 1;
    }

    return 0;
}

void get_name(char *str)
{
    while(my_get(str,20) == -1 || check_name(str) == 0)
    {
        if(check_name(str) == 0)
        {
            printf("姓名中出现除大小写以外字母,");
        }
        else
        {
            printf("姓名太长超出规定范围,");
        }
        printf("格式不符合要求,请重新输入:");
    }
}

void get_num(char *str, int length)
{
    while(my_get(str,length) != length - 1 || check_num(str) == 0)
    {
        if(check_num(str) == 0)
        {
            printf("出现非数字的字符,");
        }
        else
        {
            printf("需输入%d位的号码,", length - 1);
        }
        printf("格式不符合要求,请重新输入:");
    }
}

void get_address(char *str)
{
    while(my_get(str,100) == -1)
    {
        printf("地址太长超出规定范围,请重新输入:");
    }
}

int get_mode(char *str,int num)
{
    while(my_get(str,2) == -1 || check_mode(str,num) == 0)
    {
        printf("请输入1-%d之间的数字:",num);
    }

    return *str - '0';
}

char get_check(char *str)
{
    while(my_get(str,2) == -1 || check_check(str) == 0)
    {
        printf("请输入Y或N:");
    }

    return *str;

}

int read_file(Link head,Link *new_node)
{
    Node node_data;
    FILE *fp;
    fp = fopen("AddressList.txt","r");

    if(fp == NULL)
    {
        perror("fopen fail:");
        return 0;
    }

    while(fread(&node_data,sizeof(Node),sizeof(node_data)/sizeof(Node),fp) > 0)
    {
        create_node(new_node);
        strcpy((*new_node)->name,node_data.name);
        strcpy((*new_node)->hometel,node_data.hometel);
        strcpy((*new_node)->phone,node_data.phone);
        strcpy((*new_node)->address,node_data.address);

        insert_node_and_sort(head,*new_node);

        memset(&node_data,0,sizeof(node_data));
    }

    fclose(fp);

    return 1;
}

int write_file(Link head)
{
    Link p = head->next;
    Node node_data;

    FILE *fp;
    fp = fopen("AddressList.txt","w");
    int ret;

    if(fp == NULL)
    {
        perror("fopen fail:");
        return 0;
    }

    if(p == NULL)
    {
        return 1;
    }
    else
    {
        while(p != NULL)
        {
            ret = fwrite(p,sizeof(Node),sizeof(node_data)/sizeof(Node),fp);

            if(ret != sizeof(node_data)/sizeof(Node))
            {
                perror("fwrite error:");
                return 0;
            }
            p = p->next;
        }
    }

    fclose(fp);

    return 1;
}

int main()
{
    system("clear");
    welcome();

    Link head;
    Link new_node; 
    int num;
    char num_get[2];
    int flag = 1;

    create_link(&head);

    read_file(head,&new_node);

    while(flag)
    {
        num = get_mode(num_get,6);

        switch(num)
        {
            case 1:
                display(head);
                clear_screen();
                break;

            case 2:
                create_new_contact(head,&new_node);
                clear_screen();
                break;

            case 3:
                delete_contact(head);
                clear_screen();
                break;

            case 4:
                find_contact(head);
                clear_screen();
                break;

            case 5:
                alter_contact(head);
                clear_screen();
                break;

            case 6:
                flag = 0;
                break;
        }
    }

    write_file(head);

    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值