用C语言写的一个控制台界面的通讯录管理系统

陪她去流浪 桃子 2012年12月27日 编辑 阅读次数:2944

说明

RT, 用C写的, 帮别人做的作业~
主要是用链表实现了基本的插入, 删除, 修改, 访问, 遍历, 保存, 读取等的操作
以命令的方式操作~
话说还是我第一次写这类东西, 很不情愿的说, 都已经帮别人做了好几次的作业了
写了近400行代码, 容错能力还是不是很差, 可以用, 可以交差~

截图

命令后面的中括号内是该命令需要的参数~

源代码(3个文件)

分三个文件:
contact.c:主程序
list.c/list.h:链表的操作

contact.c

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

#include "list.h"

void show_help(void)
{
    printf(
        "**********************\n"
        "欢迎使用通讯录管理系统\n"
        "**********************\n\n"
        "请选择操作命令:\n"
        " h\t\t 查看此帮助信息\n"
        " v\t\t 查看所有联系人信息\n"
        " s\t\t 保存更新联系人信息到文件\n"
        " u\t\t 从文件中加载联系人信息\n"
        " n [姓名]\t 查询姓名对应的电话\n"
        " e [姓名]\t 修改指定联系人\n"
        " d [姓名]\t 删除指定联系人\n"
        " t [电话]\t 查询电话对应的姓名\n"
        " a [姓名] [电话] 新增联系人信息\n"
        " q\t\t 退出程序\n"
        "\n说明:\n"
        "\t第1次操作前请先执行命令 u 加载联系人信息\n"
        "\t退出前记得执行命令 s 保存联系人信息到文件\n"
        );
}

void do_cmd(void)
{
    char cmd[32];
    contact* pc = NULL;
    if(!list_create(&pc)) return;
    for(;;){
        char* pch = NULL;
        printf("命令>");
        fflush(stdin);
        fgets(cmd, sizeof(cmd), stdin);
        if(*cmd == '\n')
            continue;
        else if(*cmd == 'q')
            break;
        pch = strchr(cmd, '\n');
        if(pch) *pch = 0;
        if(cmd[1] && cmd[1]!=0x20) *cmd = 0;
        switch(*cmd)
        {
        case 'u':list_load(pc);break;
        case 's':list_save(pc);break;
        case 'v':list_view_all(pc);break;
        case 'h':show_help();break;
        case 'n':
        case 'e':
        case 'd':
        case 't':
        case 'a':
            {
                pch = cmd+1;
                while(*pch == 0x20 || *pch == '\t')
                    pch++;
                if(!*pch){
                    printf("命令 %c 缺少参数!\n", *cmd);
                    break;
                }
                if     (*cmd == 'n') list_view_name(pc, pch);
                else if(*cmd == 'e') list_edit(pc, pch);
                else if(*cmd == 'd') list_delete(pc, pch);
                else if(*cmd == 't') list_view_tel(pc, pch);
                else if(*cmd == 'a'){
                    //pch -> name
                    char* tel = NULL;
                    for(tel=pch; *tel && *tel!=0x20 && *tel!='\t'; tel++)
                        ;
                    if(*tel) *tel = 0;
                    tel++;
                    while(*tel && (*tel==0x20||*tel=='\t'))
                        tel++;
                    if(!*tel){
                        printf("没有电话号码, 参数不足!\n");
                        break;
                    }
                    list_add(pc, pch, tel);
                }
                break;
            }//case
        default:
            printf("未知命令!\n");
            break;
        }//switch
    }//for
    list_free(&pc);
    return;
}

int main(void)
{
    show_help();
    do_cmd();
    return 0;
}

list.h

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

typedef struct _contact{
    char name[16];
    char tel[12];
    struct _contact* next;
}contact;

int list_load(contact* phead);
void list_save(contact* pContact);
void list_edit(contact* pContact, char* name);
void list_delete(contact* pContact, char* name);
void list_view_tel(contact* pContact, char* tel);
void list_view_name(contact* pContact, char* name);
void list_view_all(contact* pContact);
int  list_create(contact** ppContact);
void list_free(contact** pp);
void list_add(contact* p, char* name, char* tel);

list.c

#include "list.h"

int list_create(contact** ppContact)
{
    contact* p = NULL;
    p = (contact*)malloc(sizeof(contact));
    if(!p){
        perror("内存分配错误");
        *ppContact = NULL;
        return 0;
    }
    memset(p, 0, sizeof(contact));
    *ppContact = p;
    return 1;
}

void list_view_all(contact* pContact)
{
    if(!pContact) return;
    pContact = pContact->next;
    while(pContact){
        printf(
            "姓名:%s\n"
            "电话:%s\n"
            "\n",
            pContact->name,
            pContact->tel
            );
        pContact = pContact->next;
    }
}

void list_view_name(contact* pContact, char* name)
{
    if(!pContact) return;
    pContact = pContact->next;
    while(pContact){
        if(!strcmp(pContact->name, name)){
            printf(
                "姓名:%s\n"
                "电话:%s\n"
                "\n",
                pContact->name,
                pContact->tel
            );
            break;
        }
        pContact = pContact->next;
    }
    if(!pContact){
        printf("没有找到该联系人!\n");
    }
}

void list_view_tel(contact* pContact, char* tel)
{
    char* pch = NULL;
    if(!pContact) return;
    pContact = pContact->next;
    for(pch=tel; *pch; pch++){
        if(!isdigit(*pch)){
            printf("电话号码格式不正确!\n");
            return;
        }
        if(*pch==0x20){
            *pch = 0;
            break;
        }
    }
    while(pContact){
        if(!strcmp(pContact->tel, tel)){
            printf(
                "姓名:%s\n"
                "电话:%s\n"
                "\n",
                pContact->name,
                pContact->tel
                );
            break;
        }
        pContact = pContact->next;
    }
    if(!pContact){
        printf("无此电话号码!\n");
    }
}

void list_delete(contact* pContact, char* name)
{
    contact* last = NULL;
    if(!pContact) return;
    last = pContact;
    for(; pContact && strcmp(pContact->name, name);){
        last = pContact;
        pContact = pContact->next;
    }
    if(!pContact){
        printf("没有此联系人:%s\n", name);
        return;
    }else{
        last->next = pContact->next;
        free(pContact);
        printf("已删除联系人:%s\n", name);
        return;
    }
}

void list_edit(contact* pContact, char* name)
{
    if(!pContact) return;
    pContact = pContact->next;
    while(pContact && strcmp(pContact->name, name))
        pContact = pContact->next;
    if(!pContact){
        printf("没有此联系人:%s\n", name);
        return;
    }else{
        char* pch = NULL;
        contact dummy;
        dummy.next = NULL;
        for(;;){
            printf("新姓名:");
            fflush(stdin);
            fgets(pContact->name, sizeof(dummy.name), stdin);
            if(*pContact->name != '\n'){
                pch = strchr(pContact->name, '\n');
                if(pch) *pch = 0;
                break;
            }else{
                continue;
            }
        }
        for(;;){
            printf("新电话:");
            fflush(stdin);
            fgets(pContact->tel, sizeof(dummy.tel), stdin);
            if(*pContact->tel == '\n'){
                continue;
            }else{
                for(pch=pContact->tel; *pch; pch++){
                    if(!isdigit(*pch)){
                        printf("联系人电话无效:%s\n", pContact->tel);
                        break;
                    }
                }
                if(!*pch) break;
                else continue;
            }

        }
        printf("修改成功!\n");
        return;
    }
}

void list_save(contact* pContact)
{
    FILE* fp = NULL;
    if(!pContact || ( pContact&&!pContact->next)){
        printf("没有数据需要保存!\n");
        return;
    }
    fp = fopen("contact.dat", "wb");
    if(!fp){
        perror("无法保存通讯录");
        return;
    }
    pContact = pContact->next;
    while(pContact){
        fwrite(pContact, 1, sizeof(contact), fp);
        pContact = pContact->next;
    }
    printf("所有联系人信息均已保存更新!\n");
    fclose(fp);
    return;
}

void list_add(contact* p, char* name, char* tel)
{
    contact dummy;
    char* pch = NULL;
    dummy.next = NULL;
    if(!p) list_create(&p);
    if(!p) return;
    while(p->next)
        p = p->next;
    list_create(&p->next);
    if(!p->next) return;
    strncpy(p->next->name, name, sizeof(dummy.name));
    for(pch=tel; *pch; pch++){
        if(!isdigit(*pch)){
            printf("电话号码格式不正确!\n");
            break;
        }
    }
    if(*pch){
        free(p->next);
        p->next = NULL;
        return;
    }
    strncpy(p->next->tel, tel, sizeof(dummy.tel));
    printf(
        "新增联系人:\n"
        "   姓名:%s\n"
        "   电话:%s\n",
        p->next->name, p->next->tel
        );
    p->next->next = NULL;
    return;
}

int list_load(contact* phead)
{
    FILE* fp = NULL;
    size_t file_size = 0;
    int count = 0;
    contact dummy = {0};
    if(!phead){
        printf("请先初始化!\n");
        return 0;
    }
    if(phead->next){
        printf("请不要重复初始化/加载文件!\n");
        return 0;
    }
    fp = fopen("contact.dat", "rb");
    if(!fp){
        if(errno == ENOENT){
            printf("没有找到任何联系人信息!\n");
            phead->next = NULL;
            return 1;
        }else{
            perror("读取联系人信息时错误");
            return 0;
        }
    }
    fseek(fp, 0, SEEK_END);
    file_size = ftell(fp);
    if(file_size%sizeof(contact)){
        printf("通讯录文件格式不正确!\n");
        fclose(fp);
        return 0;
    }
    rewind(fp);
    while(fread(&dummy, 1, sizeof(dummy), fp) == sizeof(dummy)){
        phead->next = (contact*)malloc(sizeof(contact));
        if(!phead->next){
            perror("分配内存出错");
            continue;
        }
        memcpy(phead->next, &dummy, sizeof(contact));
        phead->next->name[sizeof(dummy.name)-1] = 0;
        phead->next->tel[sizeof(dummy.tel)-1] = 0;
        phead = phead->next;
        phead->next = NULL;
        ++count;
    }
    fclose(fp);
    printf("共找到 %d 条联系人信息!\n\n", count);
    return 1;
}

void list_free(contact** pp)
{
    contact* q = NULL;
    contact* p = *pp;
    while(p){
        q = p->next;
        free(p);
        p = q;
    }
    *pp = NULL;
    return;
}

标签:C语言 · 代码片段 · 控制台