题目要求
可以存储1000人的信息,
个人信息包括姓名、电话、住址、年龄、性别。
提供方法:
1、添加联系人信息
2、删除指定联系人信息
3、查找指定联系人信息
4、修改指定联系人信息
5、显示所有联系人信息
6、清空所有联系人信息
7、以名字排序所有联系人
实现的功能以及所用知识
1、从文件读取和向文件写入信息
fopen、fclose、fscanf、fprintf
2、动态开辟空间存储联系人信息
malloc、realloc、free
3、添加按地址排序
offsetof、qsort、strcmp
4、转移表
函数指针数组
代码
tel.h
#ifndef __TEL_H__
#define __TEL_H__
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <search.h>
#include <malloc.h>
#include <assert.h>
#include <stddef.h>
#define NAME 20
#define SEX 5
#define PHONE 11
#define ADDRESS 20
#define EXPANSION 5
struct contact
{
char name[NAME];
char sex[SEX];
unsigned short age;
char phone[PHONE];
char address[ADDRESS];
};
struct addressBook
{
int num;
int sz;
struct contact* contacts;
};
void init_addressBook(struct addressBook* );
void read_file(struct addressBook*, FILE*);
void add_contact(struct addressBook*);
void delete_contact(struct addressBook*);
void lookup_contact(struct addressBook*);
void modify_contact(struct addressBook*);
void show_contact(struct addressBook*);
void empty_contact(struct addressBook*);
void sort_contact(struct addressBook*);
void write_file(struct addressBook*, FILE*);
#endif //__TEL_H__
text.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "tel.h"
void menu()
{
printf("************************************\n");
printf("******** menu *******\n");
printf("******* 1,add 2,delete ******\n");
printf("******* 3,lookup 4,modify ******\n");
printf("******* 5,show 6,empty ******\n");
printf("******* 7,sort 0,exit ******\n");
printf("************************************\n");
}
int main()
{
struct addressBook list;
init_addressBook(&list);
FILE *stream = fopen("text.txt", "r");
read_file(&list, stream);
fclose(stream);
void(*operate_contact[8])(struct addressBook*) = \
{ NULL, add_contact, delete_contact, lookup_contact, \
modify_contact, show_contact, empty_contact, sort_contact };
//上面是一个转移表——函数指针数组的定义和赋值
unsigned int input = 0;
do{
menu();
printf("Please choose the operation of mail list >:\n");
scanf("%d", &input);
if (input > 7)
printf("\nChoice is false, please choose again >:\n");
else if (input > 0)
operate_contact[input](&list);
//上面是转移表的使用
} while (input);
stream = fopen("text.txt", "w");
write_file(&list, stream);
fclose(stream);
free(list.contacts);
list.contacts = NULL;
return 0;
}
mailList.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "tel.h"
void read_file(struct addressBook* plist, FILE* stream)
{
assert(stream != NULL);
fscanf(stream, "%d", &plist->sz);
if (plist->sz == 0)
return;
if (plist->sz > EXPANSION)
{
plist->contacts = realloc(plist->contacts,\
plist->sz*sizeof(struct contact));
plist->num = plist->sz;
}
int i;
for (i=0; i < plist->num; i++)
{
fscanf(stream, "%s%s%d%s%s", plist->contacts[i].name,\
plist->contacts[i].sex, &plist->contacts[i].age,\
plist->contacts[i].phone, plist->contacts[i].address);
}
}
void init_addressBook(struct addressBook* plist)
{
plist->num = EXPANSION;
plist->sz = 0;
plist->contacts = malloc(EXPANSION*sizeof(struct contact));
}
static struct contact* find_contact(struct addressBook* plist)
{
int i;
char name[NAME] = { 0 };
printf("Please enter name >:\n");
scanf("%s", name);
for (i = 0; i < plist->sz; i++)
{
if (strcmp(plist->contacts[i].name, name) == 0)
return (&plist->contacts[i]);
}
return NULL;
}
static void expand(struct addressBook* plist)
{
plist->contacts = realloc(plist->contacts, \
sizeof(struct contact)*(plist->num + EXPANSION));
plist->num += EXPANSION;
}
void empty_contact(struct addressBook* plist)
{
plist->num = 0;
plist->sz = 0;
}
void add_contact(struct addressBook* plist)
{
if (plist->sz == plist->num)
{
expand(plist);
}
printf("Please enter name >:\n");
scanf("%s", plist->contacts[plist->sz].name);
printf("Please enter sex >:\n");
scanf("%s", plist->contacts[plist->sz].sex);
printf("Please enter age >:\n");
scanf("%d", &plist->contacts[plist->sz].age);
printf("Please enter phone number >:\n");
scanf("%s", plist->contacts[plist->sz].phone);
printf("Please enter address >:\n");
scanf("%s", plist->contacts[plist->sz].address);
plist->sz++;
}
void delete_contact(struct addressBook* plist)
{
struct contact* con = find_contact(plist);
if (con == NULL)
{
printf("Without the contact information.\n");
return;
}
int i = (char*)(&plist->contacts[plist->sz]) - (char*)con;
char* dest = (char*)con;
char* src = (char*)(con + 1);
while (i--)
{
*dest++ = *src++;
}
plist->sz--;
}
void lookup_contact(struct addressBook* plist)
{
struct contact* con = find_contact(plist);
if (con == NULL)
{
printf("Without the contact information.\n");
return;
}
printf("%-20s%-10s%-10s%-15s%-20s\n", \
"name", "sex", "age", "phone", "address");
printf("%-20s%-10s%-10d%-15s%-20s\n", con->name, \
con->sex, con->age, con->phone, con->address);
}
void modify_contact(struct addressBook* plist)
{
struct contact* con = find_contact(plist);
if (con == NULL)
{
printf("Without the contact information.\n");
return;
}
else
{
printf("Please enter sex >:\n");
scanf("%s", plist->contacts[plist->sz].sex);
printf("Please enter age >:\n");
scanf("%d", &plist->contacts[plist->sz].age);
printf("Please enter phone number >:\n");
scanf("%s", plist->contacts[plist->sz].phone);
printf("Please enter address >:\n");
scanf("%s", plist->contacts[plist->sz].address);
}
}
void show_contact(struct addressBook* plist)
{
if (plist->sz == 0)
{
printf("No contact to show.\n");
return;
}
printf("%-20s%-10s%-10s%-15s%-20s\n",\
"name", "sex", "age", "phone", "address");
int i;
for (i = 0; i < plist->sz; i++)
{
printf("%-20s%-10s%-10d%-15s%-20s\n",
plist->contacts[i].name, plist->contacts[i].sex,
plist->contacts[i].age, plist->contacts[i].phone,
plist->contacts[i].address);
}
}
void empt_contact(struct addressBook* plist)
{
plist->sz = 0;
}
static int compare_name(const void* name1, const void* name2)
{
return strcmp((char*)name1, (char*)name2);
}
static int compare_address(const void* name1, const void* name2)
{
int dev = offsetof(struct contact, address);
return strcmp((char*)name1+dev, (char*)name2+dev);
}
void sort_contact(struct addressBook* plist)
{
printf("Please choose the sorting method >:\n\
1.by name 2.by address\n");
int choice;
scanf("%d", &choice);
if (choice%2)
qsort(plist->contacts, plist->sz, sizeof(struct contact), compare_name);
else
qsort(plist->contacts, plist->sz, sizeof(struct contact), compare_address);
}
void write_file(struct addressBook* plist, FILE* stream)
{
assert(stream != NULL);
fprintf(stream, "%d\n", plist->sz);
int i;
for (i = 0; i < plist->sz; i++)
{
fprintf(stream, "%s %s %d %s %s\n", plist->contacts[i].name,
plist->contacts[i].sex, plist->contacts[i].age,
plist->contacts[i].phone, plist->contacts[i].address);
}
}