一、添加的功能和未解決的問題
添加:數據同步,在上一次意外退出或者未保存的情況下退出,再次進入可以選擇還原上一次的數據
問題:每次進入都會選擇是否還原,不管上次有無操作
二、代碼
主函數
#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);
}