补充!!!这次的代码有些bug我没改,若是想看修改后的请看预备役14.
=====================================================
最近一直在码项目。直到今天,终于正式的完成了一个属于自己的第一个项目。虽然可能有些不足,有些地方确实也需要修改,但是大体功能是实现了的,对我来说也是一个挑战和突破,再写的过程中,我也逐渐认清楚自己是要走项目还是要走算法的道路。下面我就对于这次项目做一个总结。
这一次我写了一个简单的通讯录。其核心就是链表和对文件的处理。可能有些功能并不完善,如果有好的建议,请写在评论区,我会及时修改或者改进。刚开始我对于链表并不熟悉,只能说看得懂但远远没到会用,会写的程度。于是我只能边学边写,进度很缓慢。
首先是主程序:
int x;
link();//把文件内容导入链表
menu();//打印菜单
printf("请输入你的选择n");
scanf("%d", &x);
while (x)
{
switch (x)
{
case 1:
add();
break;
case 2:
del();
break;
case 3:
update();
break;
case 4:
search();
break;
case 5:
save();
break;
case 6:
display();
break;
case 7:
delall();
break;
case 8:
Count();
break;
default:
printf("输入错误,请重新输入!");
break;
}
menu();
scanf("%d", &x);
if (x == 0)
{
break;
}
}
这里我写了一个link函数,因为我要对文件里边的内容进行导入到链表。所以在程序执行前会调用它,后面没什么好说的,就是简单的用switch来调用不同函数功能。
接着是第一个功能,添加联系人,先上代码:
void add()
{
char s;
while (1)
{
p1 = (struct node *)malloc(LEN);
p2->next = p1;
p2 = p1;
printf("请输入联系人姓名:");
scanf("%s", p2->content.name);
printf("请输入联系人地址:");
scanf("%s", p2->content.adress);
printf("请输入联系人电话号码:");
scanf("%s", p2->content.number);
printf("请输入联系人邮箱:");
scanf("%s", p2->content.email);
getchar();
printf("添加联系人成功!n你是否想继续存储?(Y or N):");
scanf("%c", &s);
if (s == 'Y')
continue;
else
break;
}
p2->next = NULL;
printf("n");
}
这里因为我先调用了link函数把文件里面的内容导入链表,所以现在我就不需要再一次创建链表,只需要在节点后面继续开辟新空间就行。这里我当时因为找不准节点的接入,一直出错,debug好久。。。。。
然后就是删除联系人:
void del()
{
char m[100];
char k;
p = q = head;
printf("请输入你想要删除的联系人姓名:");
scanf("%s", m);
getchar();
struct node *h = head;
while (q != NULL)
{
if (strcmp(q->content.name, m) == 0 && q == head)
{
head = head->next;
printf("删除成功!n");
}
else if (strcmp(q->content.name, m) == 0)
{
p->next = q->next;
free(q);
printf("删除成功!n");
}
else
{
p = q;
q = q->next;
continue;
}
printf("你是否要继续删除?n继续输入'Y'否则输入'N':");
scanf("%c", &k);
getchar();
if (k == 'Y')
{
printf("请输入你想要删除的联系人姓名:");
scanf("%s", m);
getchar();
q = p = head;
continue;
}
else if (k == 'N')
break;
}
}
这个就很简单了,就是对链表进行删除,就是对链表进行遍历,找出我们先要删除的联系人,如果是第一个节点,我们就让头指针往下移一个。如果不是,我们就用双指针进行删除。
下一个是修改联系人:
void update()
{
char k;
p2 = p1 = head;
char m[100], n[100];
if (head == NULL)
printf("通讯录中无可修改的联系人!n");
while (p1 != NULL)
{
printf("请输入你想修改的联系人名字:");
scanf("%s", m);
getchar();
if (strcmp(p1->content.name, m) == 0)
{
printf("请输入联系人新的姓名:");
scanf("%s", p1->content.name);
printf("请输入联系人新的地址:");
scanf("%s", p1->content.adress);
printf("请输入联系人新的电话:");
scanf("%s", p1->content.number);
printf("请输入联系人新的邮箱:");
scanf("%s", p1->content.email);
printf("修改成功!");
p1 = head;
}
else
{
p1 = p1->next;
continue;
}
getchar();
printf("你是否想继续修改?继续输入'Y'否则输入'N':");
scanf("%c", &k);
if (k == 'Y')
continue;
else if (k == 'N')
break;
}
}
修改联系人,就是对结构体进行重新赋值,这个没什么可说的。
接着是查找联系人:
void search()
{
char m[100], k;
p1 = head;
printf("请输入你想要查询的联系人姓名 :");
scanf("%s", m);
getchar();
if (head == NULL)
printf("通讯录中无可查询的联系人!n");
while (p1 != NULL)
{
if (strcmp(p1->content.name, m) == 0)
Printf(m);
else
{
p1 = p1->next;
continue;
}
printf("你想继续查询联系人吗?n继续输入'Y'否则输入'N':");
scanf("%c", &k);
getchar();
if (k == 'Y')
{
p1 = head;
printf("请输入你想查询的联系人姓名:");
scanf("%s,m");
continue;
}
else if (k == 'N')
break;
}
}
这里我用了一个函数进行封装,每次只需要在链表中找到对应联系人,在调用函数就行了。
还有就是存储数据,也就是把链表内容导入文件:
void save()
{
q = head;
FILE *fp = fopen("C:\Users\JY\Desktop\通讯录.txt", "w+");
//这里要把打开文件改成自己电脑里的路径!
while (q != NULL)
{
fprintf(fp, "%sn", q->content.name);
fprintf(fp, "%sn", q->content.adress);
fprintf(fp, "%sn", q->content.number);
fprintf(fp, "%sn", q->content.email);
q = q->next;
}
printf("保存成功!n");
fclose(fp);
}
因为刚学的C,对于文件这一块可以说是完全不懂,甚至没接触过,只知道这里一个小小的w+,让我找了三天没找来,还差点把代码修改炸了。其实文件会用也不难,如果要涉及底层原理,比如说是如何把文本文件与程序进行互相导入导出,如何导入到二进制文件中,以及缓冲区和输出流等等的原理,要理解起来是要费点时间的。因为时间紧迫,我就没能一一深入了解。总归来说,FILE* fp=fopen(“文件路径”,“打开方式”)是打开文件的必要条件,结束之后要记得关闭文件,但是好像程序结束也能关闭。
最后一个就是打印链表。这个也挺简单的:
void display()
{
p1 = head;
if (head == NULL)
printf("此文件中无联系人!n");
else
{
while (p1 != NULL)
{
printf("=============================n");
printf("姓名:%st", p1->content.name);
printf("地址:%st", p1->content.adress);
printf("电话号码:%st", p1->content.number);
printf("电子邮箱:%stn", p1->content.email);
printf("=============================n");
p1 = p1->next;
printf("n");
}
}
printf("n");
}
这里没什么好说的,完全就是对链表进行打印。
对于这一次的项目,我深深的感受到了什么叫做debug的痛苦,因为对与链表和文件的不熟练,导致我花费在改代码的时间比我写代码的时间还要长,让我一度很痛苦,不过好在今天终于把bug全部改完了。就希望自己以后能多注意点细节处理,然后把底层原理给弄懂,这样处理代码的时候就能够简单一些吧。