c语言 数据结构 课程设计 源码
infoBook.c
#include "dataStruct.h"
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#define MAXSIZE 200
#define SAVEALL 0
#define APPEND 1
void add(list li, node newnd)
{
li->count++;
/*更改插入结点的前后关系*/
node temp = li->top->pre;
li->top->pre = newnd;
newnd->next = li->top;
newnd->pre = temp;
newnd->pre->next = newnd;
}
void order(list li)
{
/*采用插入排序,找到应插入的位置*/
node tail = li->top->pre;
node pre = tail->pre;
for (int n = 1; n < li->count; n++)
{
if (strcmp(tail->name, pre->name) < 0)
{
pre = pre->pre;
}
}
/*将待排序的尾结点从链表中移除,并将其插入pre所指结点之后*/
li->top->pre = tail->pre; //更改尾节点
tail->pre->next = li->top;
pre->next->pre = tail;
tail->next = pre->next; //插入
pre->next = tail;
tail->pre = pre;
}
void save(char *filename, list li, int type)
{
FILE *fp = NULL;
node buff = NULL;
if (type == APPEND)
{
if ((fp = fopen(filename, "ab")) != NULL)
{
buff = li->top->pre;
fprintf(fp, "%s %s %s/n", buff->name, buff->tell, buff->city);
}
else
{
/*处理文件打开错误*/
printf("can not append into file ");
getchar();
exit(1);
}
}
else if (type == SAVEALL)
{
if ((fp = fopen(filename,"w")) != NULL)
{
/*将链表的记录个数写入文件的第一个字符*/
char recordNum = li->count + '0';
printf("%c", recordNum);
fputc(recordNum, fp);
/*依次写入每个记录*/
buff = li->top;
for (int n = 1; n <= li->count; n++)
{
buff = buff->next;
fprintf(fp, "%s %s %s/n", buff->name, buff->tell, buff->city);
}
}
}
else
{
printf("type error ");
}
fclose(fp);
}
void enter(list li)
{
node newnd = (node)malloc(MAXSIZE);
printf("please enter new name tell and city:/n");
scanf("%s%s%s", newnd->name, newnd->tell, newnd->city);
printf("oK!/n");
add(li, newnd); //添加新结点
order(li); //对新结点排序
}
void display(list li)
{
/*打印显示链表中所有的记录*/
printf(" *******infobook******/n");
printf(" name tell city/n");
node curr = li->top->next;
while(curr != li->top)
{
printf(" %-20s%-20s%-10s/n", curr->name, curr->tell, curr->city);
curr = curr->next;
}
}
void displayone(node curr)
{
/*打印单个记录*/
printf(" %-20s%-20s%-10s/n", curr->name, curr->tell, curr->city);
}
void load(char *filename, list li)
{
/*将文件中的记录装入链表*/
FILE *fp = NULL;
node newnd = NULL;
if ((fp = fopen(filename, "r")) != NULL)
{
int count = fgetc(fp) - '0';//从文件读取第一个字符,为记录的数目
/*逐个装进链表里*/
for (int n = count; n > 0; n--)
{
newnd = (node)malloc(MAXSIZE);
fscanf(fp,"%s %s %s/n", newnd->name, newnd->tell, newnd->city);
add(li, newnd);
}
}
fclose(fp);
}
void dele(list li, node curr)
{
int in = 0;
printf("Do you want to delete this record?(Y-1/N-0)");
in=scanf("%d", &in);
if (in)
{
/*双链表的删除结点操作*/
curr->pre->next = curr->next;
curr->next->pre = curr->pre;
free(curr);
li->count--;
}
}
void search(list li)
{
node temp = NULL; //用于链表遍历的临时结点
char name[20] = " ";
printf("please input the name you want to search:/n");
scanf("%s", name);
temp = li->top->next;
/*字符串逐个比较查找*/
for (int n = li->count; n>0; n--)
{
if (strcmp(temp->name, name))
{
temp = temp->next;
}
else
{
displayone(temp);
dele(li, temp);
return;
}
}
printf("Sorry! Name :%s does not exit/n", name);
}
void main()
{
int type = 0;
list li = (list)malloc(sizeof(LinkedList));
node top = (node)malloc(sizeof(Node));//链表的头结点
top->pre = top;
top->next = top;
li->top = top;
li->curr = top;
li->count = 0;
load("d://infobook.txt", li);
menu:
printf(" *******MainMenu******/n");
printf(" 1: display all members /n");
printf(" 2: enter new member /n");
printf(" 3: find tell by name /n");
scanf("%d", &type);
switch(type)
{
case 1:
{
display(li);
goto menu; //在这使用goto是为了实现循环操作的效果
}
case 2:
{
enter(li);
goto menu;
}
case 3:
{
search(li);
goto menu;
}
default:
{
/*重新保存*/
save("d://infobook.txt", li, SAVEALL);//可以更改路径
break;
}
}
}
dataStruct.h
typedef struct Node
{
char name[20];
char city[10];
char tell[20];
Node *pre;
Node *next;
}Node, *node;
typedef struct LinkedList
{
node top;
node curr;
int count;
}LinkedList, *list;
D盘下infobook.txt的内容格式(第一个数字字符为通讯录的当前记录数,之后按“姓名 电话 籍贯”格式)
4lifudang 12333333 hunan
pancong 13233675132 jianxi
wangguoyng 13233675132 fujian
yangwenchegn ng heilongjiang