[题集]指针与文件
题目:编写一款通讯录,用于数据的增删改查存
思路:
- 利用w形式打开文件
- 创建一条链表,管理原有数据,新数据将添加到链表尾端
- 增删改查四个功能实现
- 退出程序的时候将链表里的数据存入文件中
代码:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct tel
{
char name[10];//姓名
char sex[5];//性别
char tela[20];//电话
char mailbox[20];//邮箱
char address[20];//地址
char remark[50];//备注
struct tel* next;
};
typedef struct tel TEL;
TEL* new_nod;//控制新的数据
TEL* head, * s1, * s2, * prev;//控制单向链表
FILE* fptr;
/*功能函数*/
void go_tel();
void zen();
void san();
void gai();
void cha();
void tui();
void lie();
int count = 0;
char fot[20];//文件名
/*主函数*/
int main()
{
char ch;
char name[10], sex[5], tela[20], mailbox[20], address[20], remark[50];
head = (TEL*)malloc(sizeof(TEL));
head->next = NULL;
printf("注意事项:文件请用文本(txt)格式打开");
printf("\n请输入通讯录的文件名:\n");
gets(fot);
/*打开一个文件,若没有,则重建*/
if ((fptr = fopen(fot, "r")) == NULL)
{
printf("打开失败\n");
printf("新建文件\n");
if ((fptr = fopen(fot, "w")) == NULL);
{
printf("新建成功\n\n");
}
}
/*统计文件中原有的数据*/
while (fscanf(fptr, "%s\n %s\n %s\n %s\n %s\n %s\n", name, sex, tela, mailbox, address, remark) != EOF)
{
count++;
}
printf("\n暂时有%d项数据存在文件中\n", count);
go_tel();
while (1)
{
printf("=========================\n");
printf("=\t1.添加新的数据\t=\n");
printf("=\t2.查找一项数据\t=\n");
printf("=\t3.修改一项数据\t=\n");
printf("=\t4.删除一项数据\t=\n");
printf("=\t5.列出所有数据\t=\n");
printf("=\t6.退出系统\t=\n");
printf("=========================\n\n");
printf("请输入需要的功能序号\n");
ch = getch();
switch (ch)
{
case'1':
zen();
break;
case'2':
cha();
break;
case'3':
gai();
break;
case'4':
san();
break;
case'5':
lie();
break;
case'6':
tui();
break;
}
}
system("pause");
return 0;
}
/*功能函数*/
void go_tel()
{
/*创建原有链表,将文件内的数据读取到结构体中创建一个链表*/
if (count != 0)
{
s1 = head;
while (count!=0)
{
rewind(fptr);
prev = (TEL*)malloc(sizeof(TEL));
prev->next = NULL;
fscanf(fptr, "%s\n", prev->name);
fscanf(fptr, "%s\n", prev->sex);
fscanf(fptr, "%s\n", prev->tela);
fscanf(fptr, "%s\n", prev->mailbox);
fscanf(fptr, "%s\n", prev->address);
fscanf(fptr, "%s\n", prev->remark);
s1->next = prev;
s1 = s1->next;
count--;
}
}
else
{
printf("\n未找到原文件信息\n");
s1 = head;
}
}
void zen()
{
/*创建新的链表*/
s1 = head;
new_nod = (TEL*)malloc(sizeof(TEL));
printf("请输入姓名:");
scanf("%s", new_nod->name);
printf("请输入性别:");
scanf("%s", new_nod->sex);
printf("请输入电话:");
scanf("%s", new_nod->tela);
printf("请输入邮箱:");
scanf("%s", new_nod->mailbox);
printf("请输入地址:");
scanf("%s", new_nod->address);
printf("请输入备注:");
scanf("%s", new_nod->remark);
if (s1->next == NULL)
{
s1->next = new_nod;
new_nod->next = NULL;
}
else
{
while (s1->next != NULL)
{
s1 = s1->next;
}
s1->next = new_nod;
new_nod->next = NULL;
}
printf("\n添加成功\n");
}
void tui()
{
printf("\n正在退出\n");
system("pause");
//重新进行文件操作!
if ((fptr = fopen(fot, "w")) == NULL)
{
printf("文件保存失败!");
exit(1);
}
s1 = head->next;
while (s1 != NULL)
{
fprintf(fptr, "%s\n", s1->name);
fprintf(fptr, "%s\n", s1->sex);
fprintf(fptr, "%s\n", s1->tela);
fprintf(fptr, "%s\n", s1->mailbox);
fprintf(fptr, "%s\n", s1->address);
fprintf(fptr, "%s\n\n", s1->remark);
s1 = s1->next;
}
fclose(fptr);
exit(0);
}
void lie()
{
s1 = head->next;
if (s1 != NULL)
{
while (s1 != NULL)
{
printf("姓名:%s\n", s1->name);
printf("性别:%s\n", s1->sex);
printf("电话:%s\n", s1->tela);
printf("邮箱:%s\n", s1->mailbox);
printf("地址:%s\n", s1->address);
printf("备注:%s\n\n", s1->remark);
s1 = s1->next;
}
}
else
{
printf("\n未找到数据\n");
}
}
void san()
{
char chazhao;
char name_temp[10];
char tel_temp[20];
char ch;
printf("请输入需要查找的方式:1.姓名查找,2.电话查找\n");
if ((chazhao = getch()) == '1')
{
s1 = head;
s2 = head->next;
printf("请输入需要删除的姓名:");
scanf("%s", name_temp);
while (s2!=NULL && strcmp(name_temp, s2->name) != 0)
{
s1 = s2;
s2 = s2->next;
}
if (s2 == NULL)
{
printf("未找到该数据\n");
}
else
{
s1->next = NULL;
free(s2);
printf("删除成功\n");
}
}
if ((chazhao = getch()) == '2')
{
s1 = head;
s2 = head->next;
printf("请输入需要删除的电话:");
scanf("%s", tel_temp);
while (s2!=NULL && (strcmp(tel_temp, s2->name)) == 0)
{
s1 = s2;
s2 = s2->next;
}
if (s1 == NULL)
{
printf("未找到该数据\n");
}
else
{
s1->next = NULL;
free(s2);
printf("删除成功");
}
}
}
void cha()
{
char chazhao;
char name_temp[10];
char tel_temp[20];
char ch;
printf("请输入需要查找的方式:1.姓名查找,2.电话查找\n");
if ((chazhao = getch()) == '1')
{
s1 = head;
s2 = head->next;
printf("请输入需要查找的姓名:");
scanf("%s", name_temp);
while (s2 != NULL && strcmp(name_temp, s2->name) != 0)
{
s1 = s2;
s2 = s2->next;
}
if (s2 == NULL)
{
printf("未找到该数据\n");
}
else
{
printf("该数据为:\n");
printf("姓名:%s\n", s2->name);
printf("性别:%s\n", s2->sex);
printf("电话:%s\n", s2->tela);
printf("邮箱:%s\n", s2->mailbox);
printf("地址:%s\n", s2->address);
printf("备注:%s\n\n", s2->remark);
}
}
if ((chazhao = getch()) == '2')
{
s1 = head;
s2 = head->next;
printf("请输入需要查找的电话:");
scanf("%s", tel_temp);
while (s2 != NULL && strcmp(tel_temp, s2->name) != 0)
{
s1 = s2;
s2 = s2->next;
}
if (s2 == NULL)
{
printf("未找到该数据\n\n");
}
else
{
printf("该数据为:\n");
printf("姓名:%s\n", s2->name);
printf("性别:%s\n", s2->sex);
printf("电话:%s\n", s2->tela);
printf("邮箱:%s\n", s2->mailbox);
printf("地址:%s\n", s2->address);
printf("备注:%s\n\n", s2->remark);
}
}
}
void gai()
{
char chazhao;
char name_temp[10];
char tel_temp[20];
char mail_temp[20];
char address_temp[20];
char remark_temp[50];
char ch, ch2;
printf("请输入需要修改的联系人:1.姓名查找,2.电话查找\n");
if ((chazhao = getch()) == '1')
{
s1 = head;
s2 = head->next;
printf("请输入需要查找的姓名:");
scanf("%s", name_temp);
while (s2 != NULL && strcmp(name_temp, s2->name) != 0)
{
s1 = s2;
s2 = s2->next;
}
if (s2 == NULL)
{
printf("未找到该数据\n");
}
else
{
printf("该数据为:\n");
printf("姓名:%s\n", s2->name);
printf("性别:%s\n", s2->sex);
printf("电话:%s\n", s2->tela);
printf("邮箱:%s\n", s2->mailbox);
printf("地址:%s\n", s2->address);
printf("备注:%s\n\n", s2->remark);
printf("请输入你需要修改的数据:1.邮箱 2.地址 3.备注(其他序列将会跳回主菜单)\n\n");
ch2 = getch();
if (ch2 == '1')
{
printf("请输入新的邮箱:");
scanf("%s", mail_temp);
strcpy(s2->mailbox, mail_temp);
printf("修改成功\n");
}
if (ch2 == '2')
{
printf("请输入新的地址:");
scanf("%s", address_temp);
strcpy(s2->address,address_temp);
printf("修改成功\n");
}
if (ch2 == '3')
{
printf("请输入新的备注:");
scanf("%s", remark_temp);
strcpy(s2->remark, remark_temp);
printf("修改成功\n");
}
}
}
if ((chazhao = getch()) == '2')
{
s1 = head;
s2 = head->next;
printf("请输入需要查找的电话:");
scanf("%s", tel_temp);
while (s2 != NULL && strcmp(tel_temp, s2->name) != 0)
{
s1 = s2;
s2 = s2->next;
}
if (s2 == NULL)
{
printf("未找到该数据\n");
}
else
{
printf("该数据为:\n");
printf("姓名:%s\n", s2->name);
printf("性别:%s\n", s2->sex);
printf("电话:%s\n", s2->tela);
printf("邮箱:%s\n", s2->mailbox);
printf("地址:%s\n", s2->address);
printf("备注:%s\n\n", s2->remark);
printf("请输入你需要修改的数据:1.邮箱 2.地址 3.备注(其他序列将会跳回主菜单)\n\n");
ch2 = getch();
if (ch2 == '1')
{
printf("请输入新的邮箱:");
scanf("%s", mail_temp);
strcpy(s2->mailbox, mail_temp);
printf("修改成功\n");
}
if (ch2 == '2')
{
printf("请输入新的地址:");
scanf("%s", address_temp);
strcpy(s2->address, address_temp);
printf("修改成功\n");
}
if (ch2 == '3')
{
printf("请输入新的备注:");
scanf("%s", remark_temp);
strcpy(s2->remark, remark_temp);
printf("修改成功\n");
}
}
}
}
程序剖析:
数据类型利用一个结构体来实现,结构体包含了:
同时定义了五个结构体指针,一个文件指针,他们的功能剖析如下:
- new_nod指针用于生成新的节点
- head指针用于管理头节点
- s1指针用于操作当前节点
- s2指针用于操作后置节点
- prev指针用于生成新的节点(管理文件内的数据)
fptr用于管理文件重点剖析函数:
主函数:
- 先定义几个存放原有内的数据的数据,用来判断有多少组数据
- 在定义一个头节点,指针域为NULL
- 然后打开文件
- 再利用while循环逐个将数据存入临时数组内,判断文件指针能走多少次,来记录数据组数
- 到重点了,调用自定义函数,将原有数据存入一个链表当中(单向)
go_tel函数
如果原文件中有数据,则用prev指针生成新的节点,s1管理头节点,然后利用rewind函数将fp指针指向文件的首地址,在利用fscanf函数逐个将原有数据存入节点当中,知道count为0.
剩下的功能就是链表的增删该查。形成一条链表
退出程序(保存数据)
重新打开文件,s1从头开始,遍历整个链表,将链表内的数据逐个保存进文件内。
最后关闭文件。退出程序