本文介紹了我通訊錄項目各個功能的編寫過程以及大體思路。
1.頭文件以及結構體的定義
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
typedef char Elemtype;
typedef char Status;
typedef struct Node
{
Elemtype name[10];
Elemtype tel[12];
struct Node *next;
}Node,*Address_list;
2.初始化過程
申請頭結點,使用malloc函數爲頭結點分配空間,讓頭指針指向頭結點,頭結點的指針域指向NULL。
爲什麼要申請頭結點?
爲了保證處理第一個節點(非頭結點)和後面節點時候設計的算法相同,實現程序的高效性。
/************初始化****************/
Status Initaddress(Address_list *aptr)
{
Node *p=(Node *)malloc(sizeof(Node));//申請頭結點
if(p==NULL)
return ERROR;
p->next=NULL;
*aptr=p;
return OK;
}
2.插入新節點(實現新建聯繫人功能)
第一步:申請一個新結點用於記錄新聯繫人的信息
使用malloc函數,需要強制轉換。
第二步:將這個新結點插入到鏈表的最後
新申請一個tmp指針指向tmp頭結點,用while語句是tmp指針後移,直到鏈表尾部,即tmp->next的值爲NULL時,進行 如下操作:
將tmp指向新申請的結點,新節點的指針域指向NULL。
Status Insert(Address_list aptr,Elemtype e[],Elemtype f[])
{
Node *p=(Node *)malloc(sizeof(Node));
if(p==NULL)
{
printf("堆空間已滿\n");
return ERROR;
}
strcpy(p->name,e);
strcpy(p->tel,f);
Address_list tmp=aptr;
while(tmp->next!=NULL)
{
tmp=tmp->next;
if(strcmp(e,tmp->name)==0)
{
printf("此聯繫人已存在!\n");
return ERROR;
}
}
p->next=NULL;
tmp->next=p;
return OK;
}
4.刪除結點(刪除聯繫人)
第一步:找到需要刪除的結點
使用strcmp函數將需要刪除聯繫人姓名與鏈表結點中數據依次對比,相同則執行第二步刪除工作,不同與下一個結點對比,若是到鏈表結尾依然沒有找到,則代表該聯繫人不存在。
第二步:刪除該結點
Status Delete(Address_list aptr,Elemtype e[],Elemtype f[])
{
Address_list tmp=aptr;
while(1)
{
if(strcmp(e,tmp->next->name)==0)
break;
if(tmp->next->next==NULL&&strcmp(e,tmp->next->name)!=0)
{
printf("此聯繫人不存在!\n");
return ERROR;
}
tmp=tmp->next;
}
Node *tmp2=tmp->next;
strcpy(e,tmp2->name);
strcpy(f,tmp2->tel);
tmp->next=tmp2->next;
free(tmp2);
return OK;
}
5.查找聯繫人
查找與上文刪除聯繫人的第一步相同,使用strcmp函數即可,然後將該結點信息打印,較爲簡單。
Status Find(Address_list aptr,Elemtype e[],Elemtype f[])
{
Address_list tmp=aptr;
while(1)
{
if(strcmp(e,tmp->next->name)==0)
break;
if(tmp->next->next==NULL&&strcmp(e,tmp->next->name)!=0)
{
printf("此聯繫人不存在!\n");
return ERROR;
}
tmp=tmp->next;
}
strcpy(f,tmp->next->tel);
return OK;
}
6.按聯繫人姓名修改號碼
第一步:找到該結點,同上文查找
第二步:修改信息,用strcpy函數將修改後的號碼賦值給該結點的Tel域
Status Modify(Address_list aptr,Elemtype e[],Elemtype f[])
{
Address_list tmp=aptr;
while(1)
{
if(strcmp(e,tmp->next->name)==0)
break;
if(tmp->next->next==NULL&&strcmp(e,tmp->next->name)!=0)
{
printf("此聯繫人不存在!\n");
return ERROR;
}
tmp=tmp->next;
}
strcpy(tmp->next->tel,f);
return OK;
}
7.打印函數
Status Printlist(Address_list aptr)
{
Address_list tmp=aptr;
if(NULL==tmp)
{
printf("此表爲空!\n");
return ERROR;
}
else
{
while(tmp!=NULL)
{
printf("%-10s",tmp->name);
printf("%s",tmp->tel);
printf("\n");
tmp=tmp->next;
}
printf("\n");
return OK;
}
}
8.將聯繫人按首字母排序
第一步:申請一個指針數組用於依次指向鏈表的每一個結點
第二步:將指針數組的內容進行排序
第三步:打印指針數組的內容
Status Sort(Address_list aptr)
{
int m=0;
Address_list tmp=aptr;
Node *a[100];
tmp=tmp->next;
while(tmp!=NULL)
{
a[m]=tmp;
m++;
tmp=tmp->next;
}
int i;
for(i=0;i<m-1;i++)
{
int j;
for(j=0;j<=m-2-i;j++)
{
if(strcmp(a[j]->name,a[j+1]->name)>0)
{
Node *tmp;
tmp=a[j];
a[j]=a[j+1];
a[j+1]=tmp;
}
}
}
for(i=0;i<m;i++)
{
printf("%-10s",a[i]->name);
printf("%s",a[i]->tel);
printf("\n");
}
return OK;
}
9.將通訊錄的聯繫人信息保存到另一個TXT文件中
第一步:創建新的TXT文件
第二步:將鏈表信息逐個寫入TXT文件中,用fwrite函數
Status Fwrite(Address_list aptr)
{
FILE *file=fopen("test5.txt","w+");
if(NULL==file)
{
perror("fopen");
return ERROR;
}
Address_list tmp=aptr;
tmp=tmp->next;
while(tmp!=NULL)
{
int count1=fwrite(tmp,sizeof(Node),1,file);
if(EOF==count1)
{
perror("fwrite");
fclose(file);
return ERROR;
}
tmp=tmp->next;
}
return OK;
}
10.讀取TXT文件中的聯繫人信息
第一步:打開存有聯繫人信息的TXT文件
第二步:逐個讀取聯繫人信息,用fread函數
Status Fread(Address_list aptr)
{
Address_list tmp=aptr;
FILE *file=fopen("test5.txt","a+");
if(NULL==file)
{
perror("fopen");
return ERROR;
}
fseek(file,0,SEEK_SET);
Node *p=(Node *)malloc(sizeof(Node));
while(fread(p,sizeof(Node),1,file)!=0)
{
p->next=NULL;
tmp->next=p;
tmp=tmp->next;
p=(Node *)malloc(sizeof(Node));
}
free(p);
return OK;
}
11.主函數
在主函數中引用上面寫好的各個函數,再用一個switch函數實現執行時的供能選擇。
int main()
{
Address_list Ltop;
Initaddress(&Ltop);
//Insert(Ltop,"yu","13327829295");
Fread(Ltop);
Printlist(Ltop);
Elemtype name[10];
Elemtype tel[12];
while(1)
{
int i;
printf("\t\t\t1.查看通訊錄\n");
printf("\t\t\t2.新建聯繫人\n");
printf("\t\t\t3.刪除聯繫人\n");
printf("\t\t\t4.查找聯繫人\n");
printf("\t\t\t5.按聯繫人修改號碼\n");
printf("\t\t\t6.按聯繫人姓名排序\n");
printf("\t\t\t0.終止程序\n");
scanf("%d",&i);
switch(i)
{
case 1:
Printlist(Ltop);
break;
case 2:
do
{
printf("請輸入新建聯繫人的姓名\n");
scanf("%s",name);
printf("請輸入新建聯繫人的手機號\n");
scanf("%s",tel);
}
while(!Insert(Ltop,name,tel));
Fwrite(Ltop);
break;
case 3:
do
{
printf("請輸入刪除聯繫人的姓名\n");
scanf("%s",name);
}
while(!Delete(Ltop,name,tel));
printf("刪除的聯繫人爲:%s 號碼爲%s\n",name,tel);
Fwrite(Ltop);
break;
case 4:
do
{
printf("請輸入查找聯繫人的姓名\n");
scanf("%s",name);
}
while(!Find(Ltop,name,tel));
printf("%s的號碼爲:%s\n",name,tel);
break;
case 5:
do
{
printf("請輸入要修改號碼的聯繫人姓名\n");
scanf("%s",name);
}
while(!Modify(Ltop,name,tel));
printf("請輸入修改後的號碼:\n");
scanf("%s",tel);
Modify(Ltop,name,tel);
printf("修改後%s的號碼爲:%s\n",name,tel);
Fwrite(Ltop);
break;
case 6:
Sort(Ltop);
break;
case 0:
return 0;
default:
printf("輸入選項有誤\n");
break;
}
}
return 0;
}
通訊錄項目至此結束。