通讯录编译过程遇到的经典问题,新手必看

先上代码:

#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为例;

先按要求输入来

请输入你的选择 

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);



问题2  程序退出后,再次执行程序会卡住,后来用打断点的方式发现,原来程序在 doInit()这里个函数里一直循环着

void doInit(){

    FILE *fp = fopen(filePath"r");

    if (fp != NULL) {

        fread(&contactCountsizeof(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(&contactCountsizeof(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);

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值