一、添加的功能和未解决的问题
添加:数据同步,在上一次意外退出或者未保存的情况下退出,再次进入可以选择还原上一次的数据
问题:每次进入都会选择是否还原,不管上次有无操作
二、代码
主函数
#include <stdio.h>
#include "book.h"
int main()
{
Node *head = NULL;
CreateList(&head);
//创建链表,初始化
char j;
int q = 1; //判断上次是否每保存
Restore(head); //输入上次保存的值
printf("上次退出没有保存,是否还原上次数据'y'为是,n为不是\n");
while(1)
{
scanf("%c",&j);
if('y' == j)
{
synchronous(head,&q);
break;
}
else if('n' == j)
{
FILE *fp2 = fopen("2.txt", "w");
fclose(fp2);
break;
}
}
while(1)
{
int i;
system("clear");
Menu();
printf("请选择功能:\n");
scanf("%d",&i);
Chose(head,i);//选择功能
}
return 0;
}
功能代码
#include "book.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//创建空链表
BOOL CreateList(Node **head)
{
*head = (Node *)malloc(sizeof(Node)/sizeof(char));
if(NULL == *head)
{
return FALSE;
}
(*head)->next = NULL;
return TRUE;
}
//插入
BOOL inster_last(Node *head,Data *my_data)
{
if(NULL == head || NULL == my_data)
{
return FALSE;
}
Node *pa = (Node *)malloc(sizeof(Node)/sizeof(char));
if( NULL == pa)
{
return FALSE;
}
pa->data = *my_data;
pa->next = NULL;
while(head->next)
{
head = head->next;
}
head->next = pa;
return TRUE;
}
//主界面菜单
void Menu()
{
printf("**************************************************\n");
printf("**\t\t1、添加数据\t\t\t**\n");
printf("**\t\t2、删除数据\t\t\t**\n");
printf("**\t\t3、查找数据\t\t\t**\n");
printf("**\t\t4、查看数据\t\t\t**\n");
printf("**\t\t5、清空数据\t\t\t**\n");
printf("**\t\t6、保存数据\t\t\t**\n");
printf("**\t\t7、修改数据\t\t\t**\n");
printf("**\t\t0、退出\t\t\t\t**\n");
printf("**\t\t\t 记得要保存数据哦!!**\n");
printf("**************************************************\n");
}
//删除界面菜单
void Menu_delete()
{
printf("\t\t1、按id删除数据\n");
printf("\t\t2、按name删除数据\n");
printf("\t\t3、按phone删除数据\n");
printf("\t\t4、按telephone删除数据\n");
printf("\t\t0、返回\n");
}
//查找界面菜单
void Menu_find()
{
printf("\t\t1、按id查找数据\n");
printf("\t\t2、按name查找数据\n");
printf("\t\t3、按phone查找数据\n");
printf("\t\t4、按telephone查找数据\n");
printf("\t\t0、返回\n");
}
//修改界面
void Menu_revise()
{
printf("\t\t1、按id修改数据\n");
printf("\t\t2、按name修改数据\n");
printf("\t\t3、按phone修改数据\n");
printf("\t\t4、按telephone修改数据\n");
printf("\t\t0、返回\n");
}
//删除操作保存
void del(Node *head,Data *my_data,int j)
{
FILE *fp = fopen("2.txt", "a");
if (my_detele(head, my_data) != 0)
{
printf("删除成功\n");
char str[100];
if(ID == j)
sprintf(str, "del#!%s\n",my_data->id);
else if(NAME == j)
sprintf(str, "del#@%s\n",my_data->name);
else if(PHONE == j)
sprintf(str, "del#$%s\n",my_data->phone);
else if(TELEPHONE == j)
sprintf(str, "del#*%s\n",my_data->telephone);
fputs(str, fp);
fflush(fp);
}
else
printf("删除失败\n");
sleep(1);
while (getchar() != '\n');
close(fp);
}
//修改操作保存
void rev(Node *head,Data *my_data,int j,Data *new_data)
{
FILE *fp = fopen("2.txt", "a");
if (my_revise(head, my_data,new_data) != 0)
{
printf("修改成功\n");
char str[100];
if(ID == j)
sprintf(str, "rev#!%s#%s\n",my_data->id,new_data->id);
else if(NAME == j)
sprintf(str, "rev#@%s#%s\n",my_data->name,new_data->name);
else if(PHONE == j)
sprintf(str, "rev#$%s#%s\n",my_data->phone,new_data->phone);
else if(TELEPHONE == j)
sprintf(str, "rev#*%s#%s\n",my_data->telephone,new_data->telephone);
fputs(str, fp);
fflush(fp);
}
else
printf("修改失败\n");
sleep(1);
while (getchar() != '\n');
close(fp);
}
//功能选择
void Chose(Node *head,int i)
{
int j;
Data *my_data = (Data *)malloc(sizeof(Data)/sizeof(char));
switch(i)
{
case ADD:
system("clear");
my_add(head,my_data);
break;
case DELETE:
system("clear");
Menu_delete();
printf("请选择按什么删除数据\n");
scanf("%d",&j);
detele(head,my_data,j);
break;
case FIND:
system("clear");
Menu_find();
printf("请选择按什么查找数据\n");
scanf("%d",&j);
Find(head,my_data,j);
break;
case SEEK:
Display(head);
//Read();
break;
case EXIT:
exit(-1);
break;
case CLEAR:
Clear(head);
break;
case SAVE:
Write(head);
break;
case REVISE:
system("clear");
Menu_revise();
printf("请选择按什么修改数据\n");
scanf("%d",&j);
Revise(head,my_data,j);
break;
default :
printf("无效的选项\n");
sleep(1);
break;
}
}
//添加
void my_add(Node *head,Data *my_data)
{
FILE *fp = fopen("2.txt", "a");
if(NULL == fp)
{
perror("打开文件失败");
exit(-1);
}
printf("请输入id\n");
scanf("%s",my_data->id);
printf("请输入name\n");
scanf("%s",my_data->name);
printf("请输入phone\n");
scanf("%s",my_data->phone);
printf("请输入telephone\n");
scanf("%s",my_data->telephone);
inster_last(head,my_data);
char str[100];
sprintf(str, "add#%s#%s#%s#%s\n", my_data->id,my_data->name,my_data->phone,my_data->telephone);
fputs(str, fp); // 向文件中写入一个字符串
fflush(fp);
close(fp);
}
//删除选择
void detele(Node *head,Data *my_data,int j)
{
switch(j)
{
case ID:
printf("请输入要删除的的id:\n");
scanf("%s",my_data->id);
del(head,my_data,j);
break;
case NAME:
printf("请输入要删除的的name:\n");
scanf("%s",my_data->name);
del(head,my_data,j);
break;
case PHONE:
printf("请输入要删除的的phone:\n");
scanf("%s",my_data->phone);
del(head,my_data,j);
break;
case TELEPHONE:
printf("请输入要删除的的telephone:\n");
scanf("%s",my_data->telephone);
del(head,my_data,j);
break;
case EXIT:
return;
break;
default :
printf("无效的选项\n");
sleep(1);
break;
}
}
//删除数据
BOOL my_detele(Node *head,Data *my_data)
{
if(NULL == head || NULL == my_data)
{
return FALSE;
}
int count = 0;
Node *tmp = head;
while(tmp->next)
{
if(strcmp(tmp->next->data.id,my_data->id) == 0 || 0 == strcmp(tmp->next->data.phone,my_data->phone)\
||0 == strcmp(tmp->next->data.telephone,my_data->telephone) || 0 == strcmp(tmp->next->data.name,my_data->name))
{
Node *p1 = tmp->next;
tmp->next = p1->next;
free(p1);
return TRUE;
}
/* if(new_data->name) //相同名字
{
printf("id=%s,phone=%s,telephone=%s,name=%s\n",tmp->next->data.id,\
tmp->next->data.phone,tmp->next->data.telephone,tmp->next->data.name);
count++;
}
tmp = tmp->next;
}
if(1 == count)
{
Node *tmp1 = head;
while(tmp1->next)
{
if(0 == strcmp(tmp1->next->data.name,my_data->name))
{
Node *p1 = tmp1->next;
tmp1->next = p1->next;
free(p1);
return 1;
}
tmp1 = tmp1->next;
}*/
}
return FALSE;
}
//查找选择
void Find(Node *head,Data *my_data,int j)
{
int count;
switch(j)
{
case ID:
printf("请输入要查找的的id:\n");
scanf("%s",my_data->id);
count = my_find(head,my_data);
if(count == 0)
{
printf("无此id\n");
sleep(1);
}
break;
case NAME:
printf("请输入要查找的的name:\n");
scanf("%s",my_data->name);
count = my_find(head,my_data);
if(count == 0)
{
printf("无此name\n");
sleep(1);
}
break;
case PHONE:
printf("请输入要查找的的phone:\n");
scanf("%s",my_data->phone);
count = my_find(head,my_data);
if(count == 0)
{
printf("无此phone\n");
sleep(1);
}
break;
case TELEPHONE:
printf("请输入要查找的的telephone:\n");
scanf("%s",my_data->telephone);
count = my_find(head,my_data);
if(count == 0)
{
printf("无此telephone\n");
sleep(1);
}
break;
case EXIT:
return;
break;
default :
printf("无效的选项\n");
sleep(1);
break;
}
}
//查找数据
int my_find(Node *head,Data *my_data)
{
if(NULL == head || NULL == my_data)
{
return;
}
system("clear");
int count = 0;
Node *tmp = head;
while(1)
{
while(tmp->next)
{
if(strcmp(tmp->next->data.id,my_data->id) == 0||0 == strcmp(tmp->next->data.phone,my_data->phone)\
||0 == strcmp(tmp->next->data.telephone,my_data->telephone)|| 0 == strcmp(tmp->next->data.name,my_data->name))
{
printf("id:%s\t",tmp->next->data.id);
printf("name:%s\t",tmp->next->data.name);
printf("phone:%s\t",tmp->next->data.phone);
printf("telephone:%s\n",tmp->next->data.telephone);
count++;
}
tmp = tmp->next;
}
if(0 == count)
break;
int i;
printf("\t\t\t\t请输入0退出\n");
scanf("%d",&i);
if(0 == i)
break;
}
return count;
}
//修改选择
void Revise(Node *head,Data *my_data,int j)
{
Data *new_data = (Data*)malloc(sizeof(Data));
switch(j)
{
case ID:
printf("请输入要修的的id:\n");
scanf("%s",my_data->id);
printf("请输入要修的的id:\n");
scanf("%s",new_data->id);
rev(head,my_data,j,new_data);
break;
case NAME:
printf("请输入要修改的的name:\n");
scanf("%s",my_data->name);
printf("请输入要修改的的name:\n");
scanf("%s",new_data->name);
rev(head,my_data,j,new_data);
break;
case PHONE:
printf("请输入要修改的的phone:\n");
scanf("%s",my_data->phone);
printf("请输入要修改的的phone:\n");
scanf("%s",new_data->phone);
rev(head,my_data,j,new_data);
break;
case TELEPHONE:
printf("请输入要修改的的telephone:\n");
scanf("%s",my_data->telephone);
printf("请输入要改成的的telephone:\n");
scanf("%s",new_data->telephone);
rev(head,my_data,j,new_data);
break;
case EXIT:
return;
break;
default :
printf("无效的选项\n");
sleep(1);
break;
}
}
//修改数据
BOOL my_revise(Node *head,Data *my_data,Data *new_data)
{
if(NULL == head || NULL == my_data || NULL == new_data)
{
return;
}
Node *tmp = head;
while(tmp->next)
{
if(0 == strcmp(tmp->next->data.id,my_data->id))
{
strcpy(tmp->next->data.id,new_data->id);
printf("aaa\n");
return TRUE;
}
if(0 == strcmp(tmp->next->data.name,my_data->name))
{
strcpy(tmp->next->data.name,new_data->name);
printf("bbb\n");
return TRUE;
}
if(0 == strcmp(tmp->next->data.phone,my_data->phone))
{
strcpy(tmp->next->data.phone,new_data->phone);
printf("ccc\n");
return TRUE;
}
if(0 == strcmp(tmp->next->data.telephone,my_data->telephone))
{
strcpy(tmp->next->data.telephone,new_data->telephone);
printf("ddd\n");
return TRUE;
}
tmp = tmp->next;
}
free(new_data);
return FALSE;
}
//打印
void Display(Node *head)
{
if(NULL == head)
return;
Node *tmp = head->next;
system("clear");
while(1)
{
while(tmp)
{
printf("id:%s\t",tmp->data.id);
printf("name:%s\t",tmp->data.name);
printf("phone:%s\t",tmp->data.phone);
printf("telephone:%s\n",tmp->data.telephone);
tmp = tmp->next;
}
int i;
printf("\t\t\t\t请输入0退出\n");
scanf("%d",&i);
if(0 == i)
break;
}
printf("\n");
}
//读出数据
void Read()
{
FILE *fp1 = fopen("1.txt", "r");
if(NULL == fp1)
{
perror("打开文件失败");
exit(-1);
}
int count = 0;
Data *new_data = (Data *)malloc(sizeof(Data)/sizeof(char));
if(NULL == new_data)
{
printf("创建失败\n");
return;
}
system("clear");
printf("------------------------------------------------------------------\n");
while(TRUE)
{
while(TRUE)
{
size_t ret = fread(new_data,sizeof(Data),1, fp1);
if(0 == ret)
{
if(0 == feof(fp1))
{
printf("读取失败\n");
exit(-1);
}
break;
}
printf("id:%s\t",new_data->id);
printf("name:%s\t",new_data->name);
printf("phone:%s\t",new_data->phone);
printf("telephone:%s\n",new_data->telephone);
printf("-----------------------------------------------------------\n");
}
int i;
printf("\t\t\t\t\t\t\t请输入0退出\n");
scanf("%d",&i);
if(0 == i)
break;
}
printf("\n");
fclose(fp1);
}
//清空文件夹
void Clear(Node *head)
{
FILE *fp1 = fopen("1.txt", "w");
FILE *fp2 = fopen("2.txt", "w");
if(NULL == fp1 && NULL == fp2)
{
perror("打开文件失败");
exit(-1);
}
fclose(fp1);
fclose(fp2);
while(head->next)
{
Node *p = head->next;
head->next = p->next;
free(p);
}
printf("清空文件夹成功\n");
sleep(1);
}
//保存
void Write(Node *head)
{
Node *tmp = head->next;
FILE *fp = fopen("1.txt", "w");
FILE *fp2 = fopen("2.txt", "w");
if(NULL == fp)
{
perror("打开文件失败");
exit(-1);
}
while(tmp != NULL)
{
size_t ret = fwrite(&(tmp->data),sizeof(Data),1,fp);
if(0 == ret)
{
if(0 == feof(fp))
{
printf("写入文件失败\n");
return;
}
}
tmp = tmp->next;
}
fclose(fp);
fclose(fp2);
}
//还原退出后保存的数据
void Restore(Node *head)
{
FILE *fp1 = fopen("1.txt", "r");
if(NULL == fp1)
{
perror("打开文件失败");
exit(-1);
}
while(1)
{
Node *new_index = (Node *)malloc(sizeof(Node)/sizeof(char));
if(NULL == new_index)
{
return;
}
size_t ret = fread(&(new_index->data),sizeof(Data),1,fp1);
if(0 == ret)
{
if(0 == feof(fp1))
{
printf("写入文件失败\n");
return;
}
break;
}
new_index->next = NULL;
while(head->next)
{
head = head->next;
}
head->next = new_index;
}
fclose(fp1);
}
char strSlice(char *buf,char *data[],char c)
{
char *p1 = buf;
char *p2 = buf;
int count = 0;
char num;
while(*p1)
{
if(*p1 == '!' || *p1 == '@' || *p1 == '$' || *p1 == '*')
p1++;
while(*p2 != c && *p2 != '\0')
{
if(*p2 == '!' || *p2 == '@' || *p2 == '$' || *p2 == '*')
{
num = *p2;
}
p2++;
}
if(*p2 == '\0') //操作数据中的最后一个数据
{
data[count] = p1;
count++;
break;
}
else //操作数据中的另外的数据
{
*p2 = '\0';
data[count] = p1;
count++;
p1 = ++p2;
}
}
return num;
}
//数据同步
void synchronous(Node *head,int *q)
{
FILE *fp = fopen("2.txt", "a+");
if(NULL == fp)
{
perror("打开文件失败");
exit(-1);
}
char buf[100];
Data *new_data = (Data *)malloc(sizeof(Data)/sizeof(char));//存放数据
Data *rev_data = (Data *)malloc(sizeof(Data)/sizeof(char));//存放修改的数据
printf("%p,%p",new_data,new_data);
//取出2中的操作,并且执行
while(1)
{
memset(new_data, 0, sizeof(Data));
memset(rev_data, 0, sizeof(Data));
if(fgets(buf, 100,fp) == NULL) //没有数据
{
free(rev_data);
q = 0;
break;
}
buf[strlen(buf)-1] = '\0';
char *p = buf;
while(*p++ != '#'); //找到#号键
*(p-1) = '\0'; //将buf中的#号键改成0
char *data[SIZE] = {0};
char count = strSlice(p,data,'#');
if (strcmp(buf, "add") == 0) //添加指令
{
strcpy(new_data->id,data[0]);
strcpy(new_data->name,data[1]);
strcpy(new_data->phone,data[2]);
strcpy(new_data->telephone,data[3]);
inster_last (head,new_data) ;
}
else if (strcmp(buf, "rev") == 0)
{
if(count == '!')
{
strcpy(new_data->id,data[0]);
strcpy(rev_data->id,data[1]);
}
if(count == '@')
{
strcpy(new_data->name,data[0]);
strcpy(rev_data->name,data[1]);
}
if(count == '$')
{
strcpy(new_data->phone,data[0]);
strcpy(rev_data->phone,data[1]);
}
if(count == '*')
{
strcpy(new_data->telephone,data[0]);
strcpy(rev_data->telephone,data[1]);
}
my_revise(head, new_data,rev_data);
}
else if (strcmp(buf, "del") == 0)
{
if(count == '!')
strcpy(new_data->id,data[0]);
if(count == '@')
strcpy(new_data->name,data[0]);
if(count == '$')
strcpy(new_data->phone,data[0]);
if(count == '*')
strcpy(new_data->telephone,data[0]);
my_detele(head, new_data);
}
}
free(new_data);
new_data =NULL;
fclose(fp);
}