Code Bye

通讯录管理系统的 load 函数找错

/* 通讯录 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
struct ADS
{ char name[20];
char street[20];
char city[20];
char tele[20];
struct ADS* next;
};
int total=0;      //统计通讯录人数
void Save( struct ADS *head);
struct ADS* Create()       //创建单链表,返回结构体指针
{  int total=0;
int k=0,i=0;
struct ADS *head,*p1,*p2,*p3;    //p1,p2移动,p3遍历
char saveflag;            //接收选择:Y 或 Y
head=p1=p2=NULL;
while(1)                 //循环可以实现多次添加记录
{
p1=( struct ADS*)malloc(sizeof( struct ADS));
printf(“请输入姓名或键入“*”结束\n”);
scanf(“%s”,p1->name);
if (strcmp(p1->name,”*”)==0)
{
if(total==0)
{  printf(“当前没记录……\n”);
free(p1);
return (head);        //返回头指针
}
else { break; }
}
printf(“请输入所在街道:\n”);
scanf(“%s”,p1->street);
printf(“请输入所在城市:\n”);
scanf(“%s”,p1->city);
printf(“请输入电话号码:\n”);
scanf(“%s”,p1->tele);
if (k>0)      //判断通讯录能否存在标志
{
p3=head;             //p3遍历
while(p3!=NULL)
{  if((strcmp(p1->name,p3->name)==0)&&(strcmp(p1->tele,p3->tele)==0))
{ free(p1);
printf(“记录已存在,请按任意键返回主菜单重新输入。\n”);
i=1;
getchar();break;
}
if((strcmp(p1->name,p3->name))&&(strcmp(p1->tele,p3->tele))&&(p3==p2))
{ i=0;break; }         //跳出第一个内循环
p3=p3->next;
}
if (i==1) { break; }          //跳出第二个内循环
}
if(head==NULL)          //首次创建
{ head=p1;p2=p1; }
else
{ p2->next=p1; p2=p1; }     //第二次之后p2后移
total++;    //录入成功加1
k++;
}
p2->next=NULL;
if(i==0)
{free(p1);
printf(“\n新建通讯录成功,当前共有%d个联系人,保存?(Y or N)\n”,total);
getchar();
scanf(“%c”,&saveflag);
if (saveflag==”y”||saveflag==”Y”)
Save(head);
else
printf(“未保存成功。请返回主菜单退出系统前按7保存。\n”);
}
return head;
}
void Save(struct ADS *head)
{
FILE *fp;     //定义文件指针接收fopen返回值,用于最后关闭文件
struct ADS* t;
if ((fp=fopen(“address_list.txt”,”w”))==NULL)
{
printf(“fail to open file!|\n”);
getchar();
exit(0);
}
t=head;
while(t!=NULL)
{
fprintf(fp,” %s %s %s %s\n”,t->name,t->street,t->city,t->tele);    //将链表的东西写入文件
t=t->next;
}
fclose(fp);
printf(“\n保存成功,请按任意键返回主菜单……\n”);
getchar();
getchar();
}
struct ADS* Output()
{
FILE *fp;
struct ADS *t1,*t2,*head=NULL;
char ch;
if((fp=fopen(“address_list.txt”,”r”))==NULL)
{
printf(“fail to open file!\n”);
printf(“请按任何键退出……\n”);
getchar();
exit(0);
}
ch=fgetc(fp);
if(ch==EOF)
{
printf(“文件为空,请重新建立通讯录。\n请按任意键返回主菜单……\n”);
getchar();
return(head);
}
else
{rewind(fp); }   //指针移向开头
t1=(struct ADS*)malloc(sizeof(struct ADS));   //申请动态空间,t1接下去
head=t1;
printf(“\t姓名\t街道\t 城市\t  电话号码\n”);
printf(”    –\n”);
while(!feof(fp))
{
fscanf(fp,”%s %s %s %s”,t1->name,t1->street,t1->city,t1->tele);
printf(“\t%s\t%s\t%s\t%s\t\t\n”,t1->name,t1->street,t1->city,t1->tele);
total++;
t1->next=(struct ADS*)malloc(sizeof(struct ADS));    //t1->next赋给下一个申请的结点
t2=t1;
t1=t1->next;
}
t2->next=NULL;
free(t1);
fclose(fp);
printf(“\nOK!请按任意键返回菜单……\n”);
getchar();
getchar();
return head;
}
void Search(struct ADS* head)
{
int count=1;
struct ADS* p;
int flag,searchflag=1;       //判断数据能否符合要求标志
char name[10],temp;          //存放输入的名字

p=head;             //# 漏 #
printf (“请输入查询名字:\n”);
scanf(“%s”,name);
while(p!=NULL)
{
if(strcmp(name,p->name)==0)
{
printf(“%d”,count);
count++;
printf(“\t姓名:%s\t街道:%s\t城市:%s\t电话号码:%s\n”,p->name,p->street,p->city,p->tele);
flag=1;
}
p=p->next;
}
if(flag==0)
{printf(“未找到您要的记录!\n能否重新查询? Y or N \n”);}
scanf(“%c”,&temp);
getchar();
getchar();
if(temp==”y”||temp==”Y”)   {searchflag=1;}
else {searchflag=0; system(“cls”);}
}
struct ADS* Delete(struct ADS *head)
{
struct ADS *p1,*p2,*p3;    //p3是遍历整个链表,p1,p2是用来检查目的结点
char saveflag;    //存录与否
char temp,name[10];
int  i;
p1=head;
p2=head;
p3=head;
printf(“请输入要删除的姓名:\n”);
scanf(“%s”,name);
while(p3!=NULL)          //遇到所寻结点时赋值i,进一步操作
{ if (strcmp(p3->name,name)==0)
{ i=1; break; }         //找到即赋值为1
if ((strcmp(p3->name,name)!=0)||(p3->next==NULL))
{ i=0;  }               //不存在即为0
p3=p3->next;           //p3后移
}
if(i==1)
{
while((strcmp(p1->name,name))!=0&&(p1!=NULL))
{p2=p1;               //p2(在p1前面)指向p1
p1=p1->next;          //p1后移,进行下一步
}
}
if(i==0)
{
printf(“未找到您所查找的姓名,请检查能否输入正确?\n请按任意键返回主菜单……\n”);
getchar();
}
if((i==1)&&(p1!=NULL))       //所寻结点非末结点
{
printf(“您要删除的通讯录记录为:\n\n”);
printf(“\t姓名\t街道\t城市\t\t电话号码\n”);
printf(“–\n”);
printf(“%s\t\t%s\t%s\t%s\t\t\n”,p1->name,p1->street,p1->city,p1->tele);
printf(“问一下能否删除该记录?  Y or N \n”);
scanf(“%c”,&saveflag);
if (saveflag==”y”||saveflag==”Y”)
{
if (p1==head)   head=p1->next;     //目标结点为首结点,删除
else p2->next=p1->next;   //删除非首结点的目的结点
free(p1);       //释放p1空间
printf(“删除成功,能否存录? Y or N ?\n”);
scanf(“%c”,&temp);

if (temp==”y”||temp==”Y”)
{  Save(head); total–; printf(“\nDelete ok!\n”); }     //记录减一
else
{  printf(“保存失败,请重新进行上一步操作……\n”);
printf(“请按任意键返回主菜单!\n”);
getchar();
}
}
}
return (head);
}

struct ADS*  Delete_all(struct ADS* head)
{  FILE *fp;
char ch;
getchar();
printf(“确定删除全部记录?Y or N \n”);
scanf(“%c”,&ch);
if (ch==”N”) return head;
remove(“address_list”);           //直接删除文件
if((fp=fopen(“address_list.txt”,”w”))==NULL)
printf(“fail to open file!\n”);
return 0;
}
struct ADS*  Add(struct ADS* head)        //返回结构体指针
{
char saveflag;             //存录与否
int i=0,k=0;
struct ADS *p1,*p2,*p3;     //p3遍历,p1,p2临时移动
struct ADS * add;           //add存放添加信息
p1=head;             //先让p1指向头指针
system(“cls”);
while(p1!=NULL)
{  p2=p1;
p1=p1->next;
}
printf(“请输入添加人姓名、街道、城市、电话号码:\n”);
add=(struct ADS *)malloc(sizeof(struct ADS));
scanf(“%s%s%s%s”,add->name,add->street,add->city,add->tele);
p3=head;      //p3遍历
while(p3!=NULL)
{
if((strcmp(add->name,p3->name)==0)&&(strcmp(add->tele,p3->tele)==0))
{
free(add);     //释放重复空间
printf(“记录已存在,请按任意键返回主菜单重新输入。\n”);
i=1;
getchar(); break;
}
if((strcmp(add->name,p3->name)==0)&&(strcmp(add->tele,p3->tele))&&(p3==p2))
//到了最后一个点还没有和它相同的结点时
{  i=0; break; }   // 跳出第一个循环
p3=p3->next;
}
if(i==0)
{
add->next=NULL;
if(p1==head)  head=add;
else {p2->next=add;}      //最后一个p2结点的next插入add
total++;
k++;
free(p1);
printf(“新添电话号码成功,能否存录?Y or N\n”);
getchar();
scanf(“%c”,&saveflag);
if(saveflag==”Y”||saveflag==”y”)
{  Save(head); total++; }
else
{printf(“保存失败,请重新进行上一步操作……\n”);
getchar();
}
}

return (head);
}
struct ADS* load()
{ FILE *fp;
struct ADS *p1,*p,*head=NULL;
char ch;
if((fp=fopen(“address_list”,”r”))==NULL)
//if((fp=fopen(“address_list”,”w”))==NULL)
{   printf(“fail to open file!\n”);
getchar();
exit(0);
}
/* ch=fgetc(fp);
if(ch==EOF)
{ printf(“文件为空,请返回主菜单选择1.新建。\n”);
return (head);
}
else rewind(fp);*/
p1=(struct ADS *)malloc(sizeof(struct ADS));
head=p1;
while(!feof(fp))
{  if(fread(p1,sizeof(struct ADS),1,fp)!=1)  break;
p1->next=(struct ADS *)malloc(sizeof(struct ADS));
p=p1;
p1=p1->next;

}
p1->next=NULL;
//free(p);
fclose(fp);
return head;
}
int main()
{ int n;
struct ADS *head=NULL;
while(1)               //非零为真即可无限循环
{
printf(“\n”);
printf(“\t\t\t\t\t# # # # # # # 欢迎使用 # # # # # # #   \n”);printf(“\n”);
printf(“\t\t\t\t  # # # # # # # # 通讯录管理系统 # # # # # # # # #\n”);printf(“\n”);
printf(” \t\t\t\t\t*   1.新建      *       2.显示   *\n\t\t\t\t\t*   3.新添      *       4.查询   *\n”);
printf(” \t\t\t\t\t*   5.删减      *       6.全删   *\n\t\t\t\t\t*   7.保存      *       8.退出   *\n”);
printf(“\n”);
printf(“\t\t\t\t请选择操作(1—6):\n”);printf(“\n”);
scanf(“%d”,&n);              //分支选择
switch(n)
{
case 1:head=Create();break;
case 2:head=Output();break;
case 3:head=Add(head);break;
case 4:head=load();Search(head);break;
case 5:head=Delete(head);break;
case 6:head=Delete_all(head);system(“cls”);break;
case 7:Save(head);break;
case 8:exit(0);system(“cls”);break;
default:printf(“您输入有误,请重新输入……\n”);
}
}
return 0;
}
这通讯录管理系统的查询功能由于在首次查询时没有读取文件,所以听老师建议加了个load函数进去,但是调试不了,总是出错……尴尬,哪位高手可以帮本人看看load函数哪里出错了?请指点……

解决方案

30

代码功能归根结底不是别人帮本人看或讲解或注释出来的;而是被本人静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。
提醒:再牛×的老师也无法代替学生本人领悟和上厕所!
单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。

15

你这代码写的实在。不能调试?说明你断点打的不对
本人试了下查询,load()出来居然有乱码,本人改了下load加载文件部分,你看看,希望对你有帮助
printf(”    –\n”);
while(fgets((char*)t1, sizeof(struct ADS), fp))
{
sscanf((char*)t1,”%s %s %s %s”,t1->name,t1->street,t1->city,t1->tele);
printf(“\t%s\t%s\t%s\t%s\t\t\n”,t1->name,t1->street,t1->city,t1->tele);
total++;
t1->next = t1;
memset(t1, 0, sizeof(struct ADS));
}
free(t1);

10

v=pum[0];pum++;

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明通讯录管理系统的 load 函数找错