先上代码:
#include <stdio.h>
#include <string.h>
#define NAMELEN 22
#define TELNO 12
#define N 100
//定义person结构体
typedef struct{
char name[NAMELEN];
char tel[TELNO];
} Person;
//记录联系人个数和人编号
int contactCount =0,fno =0;
//创建文件的名称,这样便于修改
char *filePath ="dadada.data";
//用宏定义方便修改
Person person[N];
void doAdd();
void doDelete();
void doUpdate();
void doSearch();
void doList();
void doWrite();
void doInit();
int verify(int,int,int);
int main(int argc,constchar * argv[]) {
//初始化
doInit();
int flag =1;
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");
//定义变量接受用户输入的选择
int no ;
//接受非数字字符
getchar();
printf("请再次输入你的选择\n");
//键盘输入no的值
scanf("%d",&no);
//功能选择
switch (no) {
case1:
doAdd();
break;
case2:
doDelete();
break;
case3:
doUpdate();
break;
case4:
doList();
break;
case5:
doSearch();
break;
case6:
printf("您正在推出程序...\n");
return0;
default:
break;
}
}
return0;
}
/**
* 删除联系人
*/
void doDelete(){
int pno;
FILE *fp =fopen(filePath,"w");
if (fp !=NULL) {
if(contactCount !=0) {
doList();
printf("请输入要删除人的编号\n");
scanf("%d",&pno);
while (!(verify(pno,1,contactCount))) {
printf("请输入要修改人的编号\n");
scanf("%d",&pno);
}
for (int i = pno; i <contactCount; i++) {
person[pno-1] =person[pno];
}
contactCount--;
doWrite();
}
}
fclose(fp);
}
/**
* 更新联系人
*/
void doUpdate(){
FILE *fp =fopen(filePath,"w");
if (fp !=NULL) {
if (contactCount !=0) {
int flag1,pno;
printf("修改姓名请按1\n修改号码请按2\n全部修改请按3\n");
scanf("%d",&flag1);
while (!(verify(flag1,1,3))) {
printf("操作有误,修改姓名请按1\n修改号码请按2\n全部修改请按3\n");
scanf("%d",&flag1);
}
doList();
printf("请输入要修改人的编号\n");
scanf("%d",&pno);
while (!(verify(pno,1,contactCount))) {
printf("无此编号,请重新输入要修改人的编号\n");
scanf("%d",&pno);
}
switch (flag1) {
case1:
printf("请输入新的姓名\n");
scanf("%s",person[pno-1].name);
doWrite();
break;
case2:
printf("请输入新的号码\n");
scanf("%s",person[pno-1].tel);
doWrite();
break;
case3:
printf("请输入新的姓名\n");
scanf("%s",person[pno-1].name);
printf("请输入新的号码\n");
scanf("%s",person[pno-1].tel);
doWrite();
break;
default:
break;
}
}
}
fclose(fp);
}
/**
* 增加联系人
*/
void doAdd(){
FILE *fp =fopen(filePath,"w");
if (fp !=NULL) {
printf("请输入姓名\n");
scanf("%s",person[contactCount].name);
printf("请输入电话\n");
scanf("%s",person[contactCount].tel);
contactCount++;
doWrite();
}
fclose(fp);
}
/**
* 按姓名查找人
*/
void doSearch(){
FILE *fp =fopen(filePath,"r");
if (fp !=NULL) {
printf("请输入你需要查找人的姓名\n");
char goal[NAMELEN];
fgets(goal,NAMELEN,stdin);
int i =0;
for (; i <contactCount; i++) {
if (!(strcmp(goal,person[i].name))) {
printf("姓名:%s电话:%s",person[i].name,person[i].tel);
break;
}
}
if (i ==contactCount) {
printf("这个人你查不到\n");
}
}
fclose(fp);
}
/**
* 显示所有人
*/
void doList(){
FILE *fp =fopen(filePath,"r");
if (fp !=NULL) {
printf("编号\t姓名\t电话\t\n");
for (int i =0; i <contactCount; i++) {
printf("%d\t%s\t%s\t\n",i+1,person[i].name,person[i].tel);
}
}
fclose(fp);
}
/**
* 初始化
*/
void doInit(){
FILE *fp =fopen(filePath,"r");
if (fp !=NULL) {
fread(&contactCount,sizeof(contactCount),1, fp);
printf("%d\n",contactCount);
for (int i =0; i <contactCount; i++) {
fread(&person[i],sizeof(Person),1, fp);
}
}else {
fp =fopen(filePath,"wb");
if (fp !=NULL) {
fwrite(&contactCount,sizeof(contactCount),1, fp);
}
}
fclose(fp);
}
/**
* 将person中的数据写入文件
*/
void doWrite(){
FILE *fp =fopen(filePath,"w");
if (fp !=NULL) {
for (int i =0; i <contactCount; i++) {
fwrite(&person[i],sizeof(Person),1, fp);
}
}
fclose(fp);
}
/**
* 判定只是否合法
*
* @param useNo 用户输入的值
* @param min 合法最小的值
* @param max 合法最大的值
*
* @return ;
*/
int verify(int useNo,int min,int max){
if (useNo > max || useNo < min) {
return0;
}
return 1;
}
先按要求输入来
请输入你的选择
1
请再次输入你的选择
1
请输入姓名
xiaoPengYou
请输入电话
110
请再次输入你的选择 到了这步不按要求来啦,这么搞
daNanHai
请输入姓名
请输入电话
120
请再次输入你的选择
4
你会发现通讯录里面显示有两个人,一个是xiaoPengYou 110 一个是 daNanHai120,
原因,因为scanf("%d",&pno);是要接受int类型的,你给个字符串,此时缓存里面是存的‘d’ 'a' 'N' 'a' 'n' 'H' 'a' 'i' ‘\n’
所以会跳过这几个字符不读取,而pno里面原本就存着上次输入的1,故选择了swich 1:的语句,当进入doAdd的
printf("请输入姓名\n"); 这句后,遇到下句时,scanf会直接从内存中将‘d’ 'a' 'N' 'a' 'n' 'H' 'a' 'i' '\n',读入 person[contactCount].name 中,故姓名中就存了 “daNanHai”
scanf("%s",person[contactCount].name);
printf("请输入电话\n");
scanf("%s",person[contactCount].tel);
void doInit(){
FILE *fp = fopen(filePath, "r");
if (fp != NULL) {
fread(&contactCount, sizeof(contactCount), 1, fp);
printf("%d\n",contactCount); //----> 此处打印发现,contactCount的值很大很大
for (int i = 0; i < contactCount; i++) {
fread(&person[i], sizeof(Person), 1, fp);
}
}else {
fp = fopen(filePath, "wb");
if (fp != NULL) {
fwrite(&contactCount, sizeof(contactCount), 1, fp);
}
}
fclose(fp);
}
最终发现原来在doWrite() 函数中
void doWrite(){
FILE *fp = fopen(filePath, "w");
if (fp != NULL) {
-----> 这里没有讲contactCount的值写入文件中,而直接写入Person 了
-----> 这就导致在去出contactCount时,是取的person[0].name 的第前4个字节,故数很大
for (int i = 0; i < contactCount; i++) {
fwrite(&person[i], sizeof(Person), 1, fp);
}
}
fclose(fp);
}