首页 > 代码库 > 【C语言疯狂讲义】(十六)C语言简易通讯录(未优化版)

【C语言疯狂讲义】(十六)C语言简易通讯录(未优化版)

《通讯录》开发用到得知识点

 

常量、变量的使用

全局变量

分支语句

函数

循环语句

scanf和printf

数据

结构体

文件

指针*


 《通讯录》中解决的经典问题


  1. 数组元素如何删除(不使用链表)

 开发调试环境:Mac os x10.10 + xcode6.1

通讯录主界面:


添加联系人界面


删除联系人界面


修改联系人界面


搜索联系人



#include <stdio.h>
#include <string.h>
/****** 宏定义 *******/
#define NAME_LEN 21
#define TEL_LEN 12
#define N 1000

/****** 函数的声明 *******/
void doAdd();
void doDelete();
void doUpdate();
void doList();
void searchPersonByName();
void init();
void writeFile();

/****** 变量定义 *******/
typedef struct Linker{

    //联系人的姓名
    char name[NAME_LEN];
    //联系人电话
    char mobileNum[TEL_LEN];
    
}Person;

//定义联系人数组
Person contacts[N];
//定义一个变量,用于存放当前联系人的个数
int totalCount=0;
//文件路径的变量
char *filePath="telbook.data";

int main(int argc, const char * argv[]) {
    
    int flag = 1;
    int num =-1;
    
    //进行初始化
    init();
    printf("数据初始化成功!...\n");
    
    while (flag) {
        
        printf("**************************\n");
        printf("****** 欢迎使用通讯录 ******\n");
        printf("****** 1、添加联系人  ******\n");
        printf("****** 2、删除联系人  ******\n");
        printf("****** 3、修改联系人  ******\n");
        printf("****** 4、查看所有联系人 ****\n");
        printf("****** 5、搜索联系人  ******\n");
        printf("****** 6、退出系统    ******\n");
        printf("**************************\n\n");
        
        printf("请选择1-6之间的一个操作\n");
        scanf("%d",&num);
        if (num<=0 || num >6) {
            printf("非法输入\n");
        }else{
           
            //判断用户选择了哪个功能
            switch (num) {
                    
                case 1:
                    doAdd();
                    break;
                case 2:
                    doDelete();
                    break;
                case 3:
                    doUpdate();
                    break;
                case 4:
                    doList();
                    break;
                case 5:
                    searchPersonByName();
                    break;
                case 6:
                    printf("正在退出系统...\n");
                    printf("退出完成!\n");
                    flag = 0;
                    break;
                    
                default:
                    break;
            }
        
        
        }
        
        
        
        
    }
    
    
    return 0;
}


/**
 *  添加联系人
    思路:
    1)提示用户输入姓名和电话号码
    2)接收用户输入的内容
    3)保存到联系人数组
    4)写入到文件中
 */
void doAdd(){

    printf("您选择的是添加联系,请按提示操作\n");
    //1)提示用户输入姓名和电话号码
    printf("请输入联系人姓名:*联系人姓名不能有空格\n");
    //2)接收用户输入的内容
    // 0   0
    // 1   1 contacts[1]
    //3)保存到联系人数组
    scanf("%s",contacts[totalCount].name);
    printf("请输入联系人电话:*联系人电话不能有空格\n");
    scanf("%s",contacts[totalCount].mobileNum);
    
    //联系人的总数要+1
    totalCount++;
    
    //4)写入到文件中
    writeFile();

}
/**
 *  删除联系人的函数
    思路: 
    1)让用户输入要删除的数据的编号
    2)判断编号是否合法
    3)让用户再次确认删除
    4)开始删除数组元素
    5)删除文件内容
 */
void doDelete(){

    printf("您选择的是删除联系,请按提示操作\n");
    doList();
    //1)让用户输入要删除的数据的编号
    int no;
    printf("请输入要删除的联系人的编号:\n");
    scanf("%d",&no);
    //2)判断编号是否合法
    if (no<=0 || no >totalCount) {
        printf("编号不存在!\n");
        return;
    }
    //3)让用户再次确认删除
    int no1;
    printf("请再次确认要删除的信息: 0.取消   1.确定\n");
    scanf("%d",&no1);
    
    if (no1) {
        //4)开始删除数组元素
        //   1)删除的元素是数组的最后一个元素
        if (no==totalCount) {
            totalCount --;
        }else{
        //   2) 删除的不是最后一个元素
            
            for (int i=no; i<totalCount; i++) {
                //后一个元素覆盖前一个元素
                contacts[no-1] = contacts[no];
                
            }
            
            totalCount--;
        //5)删除文件内容
            writeFile();
        }
    }
    
    
    
}
/**
 *  更新联系人信息
    思路:
    1)提示输入要修改的联系人编号
    2)判断编号是否合法
    3)让用户输入新的姓名、电话
    4)让用户再次确认修改
    5)开始修改用户信息
    6)更新到文件中
 
 */
void doUpdate(){

    printf("您选择的是修改联系人,请按提示操作\n");

    doList();
    //1)让用户输入要修改的数据的编号
    int no;
    printf("请输入要修改的联系人的编号:\n");
    scanf("%d",&no);
    //2)判断编号是否合法
    if (no<=0 || no >totalCount) {
        printf("编号不存在!\n");
        return;
    }
    //3)让用户输入新的姓名和电话号码
    char name[NAME_LEN];
    char tel[TEL_LEN];
    printf("请输入新的用户名:\n");
    scanf("%s",name);
    printf("请输入新的电话号码:\n");
    scanf("%s",tel);
    
    //4)让用户再次确认修改
    int no1;
    printf("请再次确认要修改的信息: 0.取消   1.确定\n");
    scanf("%d",&no1);
    
    if (no1) {
    //5)开始修改用户信息
        
        strcpy(contacts[no-1].name, name);
        strcpy(contacts[no-1].mobileNum, tel);
        
        
    //6)更新到文件中
        writeFile();

    }
}

/**
 *  查看所有的联系人
    思路:
    1)先判断联系人是否为空
    2)如果不为空,遍历数组,显示所有的联系人
 */
void doList(){

    if (totalCount==0) {
       
        printf("您的通讯录还空无一人!\n");
        
    }else{
        printf("所有的联系人信息如下:\n");
        printf("编号\t姓名\t\t电话\n");
        for (int i=0; i<totalCount; i++) {
            printf("%d\t%s\t\t%s\n",i+1,contacts[i].name,contacts[i].mobileNum);
        }
        
    }

    printf("\n");
}

/**
 *  根据联系人的姓名查找联系人
    思路:
    1)提示用户输入要查找的人的姓名
    2)遍历联系人数组,查找有没有这个人
    3)查找到了,把电话号码显示出来
    4)没有查找到,提示没有这个联系人
 */
void searchPersonByName(){

     printf("您选择的是搜索联系人,请按提示操作:\n");
     char name[NAME_LEN];
    //1)提示用户输入要查找的人的姓名
    
    printf("请输入要查找的用户名:\n");
    scanf("%s",name);
    int i;
    //2)遍历联系人数组,查找有没有这个人
    for (i=0; i<totalCount; i++) {
        
        //3)查找到了,把电话号码显示出来
        if (strcmp(contacts[i].name, name)==0) {
            printf("您查找的 %s 的电话号码是:%s\n",contacts[i].name,contacts[i].mobileNum);
            //停止循环
            break;
        }
    }
    
    //4)没有查找到,提示没有这个联系人
    if (i==totalCount) {
        printf("你的通讯录没有这个人!\n");
    }
    
    printf("\n");

}

/**
   初始化方法,用于初始化数据
   思路:
   1)尝试性的读取文件
   2)如果成功了,说明文件存在,则读取文件内容
   3)不成功,说明文件不存在,
       1)创建文件
       2)写入联系人数量
       
 
 */
void init(){

    //读取数据文件
    FILE *fp = fopen(filePath, "rb");
    
    if (fp!=NULL) {
        
        //读取到,fread读文件到数组中
        //printf("通讯录文件已经存在!\n");
        
        //先读取联系人的个数
        fread(&totalCount, sizeof(int), 1, fp);
//        printf("totalCount = %d",totalCount);
        for (int i=0; i<totalCount; i++) {
            //循环读取每一块数据
            fread(&contacts[i], sizeof(Person), 1, fp);
        }
        
    }else{
        
        //不存在,创建文件
        fp = fopen(filePath, "w");
        //当前联系人的数量保存到文件中
//        int count=1;
        //                4         1
        fwrite(&totalCount, sizeof(int), 1, fp);
        
        printf("通讯录文件创建成功!\n");
    }

    fclose(fp);
}
/**
 *  普通的写文件操作(把联系人写入到文件中)
    思路:
    1)先写联系人的长度,占用的时文件的头4个字节
    2)然后遍历数组,把数组的每一个元素都写入到文件中
 */
void writeFile(){


    FILE *fp = fopen(filePath, "wb");
    if (fp!=NULL) {
        // 1)先写联系人的长度,占用的时文件的头4个字节
        fwrite(&totalCount, sizeof(int), 1, fp);
        // 2)然后遍历数组,把数组的每一个元素都写入到文件中
        for (int i=0; i<totalCount; i++) {
            fwrite(&contacts[i], sizeof(Person), 1, fp);
        }
        
        printf("文件更新成功!\n");
    }
   
    fclose(fp);

}


【C语言疯狂讲义】(十六)C语言简易通讯录(未优化版)