C语言项目总结-通讯录

功能展示



通讯录用到的知识点

常量,变量的使用
全局变量
分支语句
函数
循环语句
scanf和printf
数据
结构体
文件
指针*
经典的问题(难点)
     数组元素的删除(涉及数据结构)

功能分析及实现步骤


//
//  main.c
//  End_project
//  通讯录
//  Created by 自超 on 15/8/31.
//  Copyright (c) 2015 自超 . All rights reserved.
//

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

// 宏定义 *******************************************************************
#define N 100   // 通讯录容量
#define NAMELEN 22   // 姓名长度
#define NUMLEN 12   // 号码长度

//********* 定义部分 ********************************************************
// 定义联系人的结构体
typedef struct {
   
// 联系人
   
char name[ NAMELEN ];
   
// 号码
   
char telNum[ NUMLEN ];
}Person;

// 存储所有联系人,联系人数组
Person contacts[ N ]; // 能够存储 100 个联系人

// 定义联系人个数
int totalContactCount = 0 ;
// 接收用户输入的编号
int fno;
// 定义数据文件保存的位置
char *filePath = "telbook.data" ;

//*********** 函数声明部分 ***************************************************
int valitataInput( int num, int min, int max); // 合法输入
void doAdd(); // 添加
void doDelete(); // 删除
void doUpdata(); // 修改
void doList(); // 显示联系人
void doSearchByName(); // 搜索
void init(); // 初始化
void writeFile(); // 写数据到文件




// 主函数 *******************************************************************
int main( int argc, const char * argv[]) {
   
   
/*
     1
、引入头文件
     2
、进行必要的宏定义
     3
、定义文件名称变量、联系人数组、联系人结构体
     4
、定义函数,并进行声明
     5
、编写循环控制程序
     6
、现实操作界面
     7
、根据编号执行不同的函数

     */

   
   
init ();
   
printf ( " 通讯录初始化完成! \n" );
   
   
while ( 1 ) {
       
       
printf ( "\n" );
       
// 软件的界面显示出来,死循环控制不停地输入
       
printf ( "**************************\n" );
       
printf ( "****** 欢迎使用通讯录 ******\n" );
       
printf ( "****** 1 、添加联系人   ******\n" );
       
printf ( "****** 2 、删除联系人   ******\n" );
       
printf ( "****** 3 、修改联系人   ******\n" );
       
printf ( "****** 4 、查看所有联系人 ****\n" );
       
printf ( "****** 5 、搜素联系人   ******\n" );
       
printf ( "****** 6 、退出系统     ******\n" );
       
printf ( "**************************\n" );
       
       
// 提示用户选择一个序号
       
printf ( " 请选择 1~6 之间的功能编号: \n" );
       
scanf ( "%d" , & fno );
       
       
// 判断编号是否合法,最好写个函数
       
valitataInput ( fno , 1 , 6 );
       
       
// 做不同的事情,定义不同的函数
       
switch ( fno ) {
           
case 1 :
               
// 执行添加
               
doAdd ();
               
break ;
           
case 2 :
               
// 执行删除
               
doDelete ();
               
break ;
           
case 3 :
               
// 执行修改
               
doUpdata ();
               
break ;
           
case 4 :
               
// 执行显示所有联系人
               
doList ();
               
break ;
           
case 5 :
               
// 执行搜索联系人
               
doSearchByName ();
               
break ;
           
case 6 :
               
printf ( " 系统正在退出 ...\n" );
               
printf ( " 系统已经退出! " );
               
return 0 ;
               
break ;
               
               
           
default :
               
break ;
        }
        
       
    }
   
   
   
   
return 0 ;
}

// 判断编号合法函数 **********************************************************
//min-1,max-6
int valitataInput( int num, int min, int max) {
   
   
if (num < min || num > max) {
        printf("非法输入!");
        return 1;    // 返回值 1 ,使 while 继续执行
    } else {
       
return 0 ;
    }
}

// 添加联系人函数 ************************************************************
/*
 1
、提示用户输入联系人姓名
 2
、接收联系人
 3
、提示用户输入电话号码
 4
、接收电话号码
 5
、确认添加
 6
、联系人个数 +1
 7
、把联系人信息写入文件中
 */

void doAdd() {
   
   
printf ( " 您选择的是添加联系人,请按提示操作: \n" );
//    1 、提示用户输入联系人姓名
   
printf ( " 请输入联系人姓名 : * 联系人姓名之间不能有空格) \n" );
//    2 、接收联系人
   
scanf ( "%s" , contacts [ totalContactCount ]. name );
//    3 、提示用户输入电话号码
   
printf ( " 请输入联系人号码 : * 联系人号码之间不能有空格) \n" );
//    4 、接收电话号码
   
scanf ( "%s" , contacts [ totalContactCount ]. telNum );
//    5 、确认添加
   
int flag;
   
printf ( " 您确认添加吗? 1. 确认   0. 取消 \n" );
   
scanf ( "%d" , &flag);
   
if (flag) {
       
//    6 、联系人个数 +1
       
totalContactCount ++;
       
//    7 、把联系人信息写入文件中
       
writeFile ();
    }
}

// 删除联系人函数 ************************************************************
/*
 1
、提示输入删除的联系人编号
 2
、判断编号是否合法,编号不能大于联系人个数
 3
、提示用户再次确认删除
 4
、开始数组元素
    1)
删除的元素正好是数组的最后一个元素
       
只需让联系人数量 -1
    2
)如果删除的元素不是数组的最后一个元素
       
需移动元素
       
联系人数量 -1
 5
、同步到文件中
 */

void doDelete() {
   
   
printf ( " 您选择的是删除联系人,请按提示操作: \n" );
   
   
doList ();
//    1 、提示输入删除的联系人编号
   
int no;
   
printf ( " 请输入要删除的联系人编号: \n" );
   
scanf ( "%d" , &no);
//    2 、判断编号是否合法,编号不能大于联系人个数
   
if ( valitataInput (no, 1 , totalContactCount )) {
       
return ;
    }
//    3 、提示用户再次确认删除
   
int flag;
   
printf ( " 删除联系人后,数据无法恢复,您确认要删除吗? 1. 确认 0. 取消 \n" );
   
scanf ( "%d" , &flag);
   
if (flag) {
   
//    4 、开始删除数组元素
   
//    1) 删除的元素正好是数组的最后一个元素
//    只需让联系人数量 -1
       
if (no == totalContactCount ) {
           
totalContactCount --;
        }
else {
   
//    2 )如果删除的元素不是数组的最后一个元素
//    需移动元素
//    联系人数量 -1
           
for ( int i = no; i < totalContactCount ; i++) {
               
// 元素的移动和覆盖
               
contacts [no - 1 ] = contacts [no];
            }
        }
//    5 、同步到文件中
       
writeFile ();
    }
}

// 修改联系人函数 ************************************************************
/*
 1
、提示用户输入修改的信息编号
 2
、验证编号是否合法
 3
、输入新的用户名和新的电话号码
 4
、让用户确认
 5
、更新数组信息
 
 */

void doUpdata() {
   
   
printf ( " 您选择的是修改联系人,请按提示操作: \n" );
   
   
doList ();
//    1 、提示输入修改的联系人编号
   
int no;
   
printf ( " 请输入要修改的联系人编号: \n" );
   
scanf ( "%d" , &no);
//    2 、判断编号是否合法,编号不能大于联系人个数
   
if ( valitataInput (no, 1 , totalContactCount )) {
       
return ;
    }
//    3 、输入新的用户名和新的电话号码
   
char newName[ NAMELEN ];
   
char newTel[ NAMELEN ];
   
printf ( " 请输入联系人新的姓名:( * 注意联系人姓名之间不能有空格) \n" );
   
scanf ( "%s" , newName);
   
   
printf ( " 请输入联系人心的电话:( * 注意联系人电话之间不能有空格) \n" );
   
scanf ( "%s" , newTel);
   
//    4 、让用户确认
   
int flag;
   
printf ( " 确认后,信息将永久修改,您确认要修改吗? 1. 确认 0. 取消 \n" );
   
scanf ( "%d" , &flag);
   
if (flag) {
//    5 、更新数组信息
       
strcpy ( contacts [no - 1 ]. name , newName);
       
strcpy ( contacts [no - 1 ]. telNum , newTel);
//    6 、写入到文件中
       
writeFile ();
    }
}

// 显示联系人函数 ************************************************************
/*
 
如果文件存在则读取文件中的所有数据,遍历
 1
、判断
    totalContactCount == 0 
表示没有联系人
 2
、如果不等于 0
   
开始遍历,并且输出联系人的信息
 */

void doList() {
   
   
printf ( " 显示所有联系人,请按提示操作: \n" );
   
if ( totalContactCount == 0 ) {
       
printf ( " 您的通讯录还没有小伙伴 ~ 请添加小伙伴! \n" );
    }
else {
       
       
// 输出格式
       
printf ( " 编号 \t 姓名 \t 电话 \t\n" );
       
// 遍历联系人数组
       
for ( int i = 0 ; i < totalContactCount ; i++) {
           
printf ( "%d\t %s\t %s\t \n" , i+ 1 , contacts [i]. name , contacts [i]. telNum );
        }
    }
   
}

// 搜索联系人函数 ************************************************************
/*
 
根据联系人的姓名查找联系人
 1
、提示用户输入要查找的联系人姓名
 2
、遍历数组,查找此人
    1
)输入的姓名和 contacts[i].name 比较
 3
、查找到了,显示电话号码
 4
、查找不到,提示查无此人
 */

void doSearchByName() {
   
   
printf ( " 您选择的是搜索联系人,请按提示操作: \n" );
   
//1 、提示用户输入要查找的联系人姓名
   
char searchName[ NAMELEN ];
   
printf ( " 请输入要查找的联系人姓名: \n" );
   
scanf ( "%s" , searchName);
   
// 遍历数组,查找此人
   
int i;
   
for (i = 0 ; i < totalContactCount ; i++) {
       
// 比较输入的姓名和 contacts[i].name 是否相等   返回值 ==0
       
if ( strcmp (searchName, contacts [i]. name ) == 0 ) {
           
// 打印此联系人对应的电话号
           
printf ( " 您搜索的联系人 %s 电话是: %s\n" , searchName, contacts [i]. telNum );
           
break ; // 查找到了,循环结束
        }
    }
   
// 查找不到,提示查无此人
   
if (i == totalContactCount ) {
       
printf ( " 查无此人!请看看是否输错! \n" );
    }
}

// 通讯录初始化函数 **********************************************************
/*
 1
、尝试性读取数据文件
 2
、如果读取成功,说明文件存在
   
如果存在,要读取联系人数据,保存到联系人数组中 contacts
 3
、如果读取失败,说明我们是第一次使用通讯录
   
如果第一次使用
    1
)创建联系人数据文件
    2
)把当前联系人的个数写入文件中 totalContactCount = 0
 */

void init() {
   
// 定义文件指针,并打开
   
FILE *fp = fopen ( filePath , "r" );
   
// 判断
   
if (fp != NULL ) {
       
// 第一步:读取联系人个数
       
fread (& totalContactCount , sizeof ( totalContactCount ), 1 , fp);
       
// 读取每一个联系人
       
for ( int i = 0 ; i < totalContactCount ; i++) {
           
// 读取每个联系人保存到联系人数组
           
fread (& contacts , sizeof ( Person ), 1 , fp);
        }
    }
else {
       
// 创建文件
        fp =
fopen ( filePath , "wb" );
       
// 写入联系人个数
       
fwrite (& totalContactCount , sizeof ( totalContactCount ), 1 , fp);
       
printf ( " 通讯录文件创建成功 ~\n" );
    }
   
   
fclose (fp);
}

// 写数据到文件 **************************************************************
/*
 1
、以 wb 的方式打开
 2
、先写联系人个数
 3
、写每个联系人数据
 */

void writeFile() {
//    1 、以 wb 的方式打开
   
FILE *fp = fopen ( filePath , "wb" );
   
if (fp != NULL ) {
       
//    2 、先写联系人个数
       
fwrite (& totalContactCount , sizeof ( totalContactCount ), 1 , fp);
       
//    3 、写每个联系人数据
       
for ( int i = 0 ; i < totalContactCount ; i++) {
           
// 每次都写入一个数据的元素
           
fwrite (& contacts [i], sizeof ( Person ), 1 , fp);
        }
       
printf ( " 写文件数据更新成功! \n" );
    }
   
// 关闭文件指针
   
fclose (fp);
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值