python通讯录管理系统各子功能算法流程图_C实现通讯录管理系统(亮点:纯链表实现、子串匹配,文件读写)...

题目:通讯录管理程序

问题描述

编写一个简单的通讯录管理程序。通讯录记录有姓名,地址(省、市(县)、街道),电话号码,邮政编码等四项。

基本要求

程序应提供的基本基本管理功能有:

1) 添加:即增加一个人的记录到通信录中

2) 显示:即在屏幕上显示所有通信录中的人员信息,应能分屏显示。

3) 存储:即将通讯录信息保存在一个文件中。

4) 装入:即将文件中的信息读入程序。

5) 查询:可根据姓名查找某人的相关信息,若找到显示其姓名、地址、电话号码和邮政编码。

6) 修改:可修改一个人的除姓名外其它信息。

测试数据

程序应输入不少于10个人员的通讯录信息,应考虑到人员可以同名的情况。

实现提示

程序可用一个结构体数组、单向链表或对象数组来管理人员信息,每个人员的姓名,地址,电话号码和邮政编码用一个结构体或类实现。

代码:

#include

#include

#include

#define CHARMAX 30

typedef struct record {

char name[CHARMAX];

char phonenumber[11];

char address[3][CHARMAX]; //0-省 1-市 2-街道

char postcode[6];

struct record *next;

} RECORD;

void PrintMenu();

void AlterString(RECORD *head);

RECORD *InputRecord(RECORD *head, int *total);

void PrintAllRecords(RECORD *head, const int *total);

RECORD *DeleteRecord(RECORD *head,int *total);

RECORD *ReviseRecord(RECORD *head);

RECORD *SearchRecord(RECORD *head, int onlyOneRecord) ;

RECORD *ImportRecords(RECORD *head, int *total);

RECORD *ExportRecords(RECORD *head);

int main() {

int total = 0, selection;

RECORD *head = NULL;

printf("Welcome to Directory Management System!\n");

printf("By XZ&YYM\n");

printf("---------------------------------------------\n");

do {

PrintMenu();

scanf("%d", &selection);

system("cls");

switch (selection) {

case 0:

break;

case 1:

head = InputRecord(head, &total);

break;

case 2:

PrintAllRecords(head, &total);

break;

case 3:

head = DeleteRecord(head,&total);

break;

case 4:

head = ReviseRecord(head);

break;

case 5:

SearchRecord(head,0);

break;

case 6:

head = ImportRecords(head,&total);

break;

case 7:

ExportRecords(head);

break;

default:

printf("\n\n-- Sorry!Please input 0-10!\n");

};

} while (selection != 0);

return 0;

}

void PrintMenu() {

printf("\n");

printf("|1.Input record\n");

printf("|2.List all records\n");

printf("|3.Delete record\n");

printf("|4.Revise record\n");

printf("|5.Search record\n");

printf("|6.Import records from file\n");

printf("|7.Export records to file\n");

printf("|0.Exit\n");

printf("|Please input 0-7 to select function :");

}

//功能:将字符串后的回车删掉

//入参:链表首地址

//出参:无

void AlterString(RECORD *head) {

int m;

RECORD *p1 = head;

while (p1 != NULL) {

for (m = 0; m < CHARMAX; m++) {

if (*((p1->name) + m) == '\n') {

*((p1->name) + m) = '\0';

}

}

for (m = 0; m < 11; m++) {

if (*((p1->phonenumber) + m) == '\n') {

*((p1->phonenumber) + m) = '\0';

}

}

for (m = 0; m < CHARMAX; m++) {

if (*((p1->address[0]) + m) == '\n') {

*((p1->address[0]) + m) = '\0';

}

}

for (m = 0; m < CHARMAX; m++) {

if (*((p1->address[1]) + m) == '\n') {

*((p1->address[1]) + m) = '\0';

}

}

for (m = 0; m < CHARMAX; m++) {

if (*((p1->address[2]) + m) == '\n') {

*((p1->address[2]) + m) = '\0';

}

}

for (m = 0; m < 6; m++) {

if (*((p1->postcode) + m) == '\n') {

*((p1->postcode) + m) = '\0';

}

}

p1 = p1->next;

}

}

//功能:连续输入数据

//入参:链表首地址,数据总数地址

//出参:链表首地址

RECORD *InputRecord(RECORD *head, int *total) {

int i = *total;

char inputChar;

RECORD *p = head, *input = (RECORD *) malloc(sizeof(RECORD));

printf("\n-- Start to Input Record\n");

//如果拥有数据,则输出现有数据总数

if (*total) {

printf("-- You have had %d records\n\n", *total);

}

do {

//输入数据

printf("Input NO.%d Record`s Name:", i + 1);

fflush(stdin);

fgets(input->name, CHARMAX + 1, stdin);

printf("Input NO.%d Record`s Phone Number:", i + 1);

fflush(stdin);

fgets(input->phonenumber,CHARMAX + 1, stdin);

printf("Input NO.%d Record`s Address:\n", i + 1);

printf("- Input NO.%d Record`s Province:", i + 1);

fflush(stdin);

fgets(input->address[0], CHARMAX + 1, stdin);

printf("- Input NO.%d Record`s City:", i + 1);

fflush(stdin);

fgets(input->address[1], CHARMAX + 1, stdin);

printf("- Input NO.%d Record`s Street:", i + 1);

fflush(stdin);

fgets(input->address[2], CHARMAX + 1, stdin);

printf("- Input NO.%d Record`s Postcode:", i + 1);

fflush(stdin);

fgets(input->postcode, 7, stdin);

input->next = NULL; //插入时放于链表的最后

//插入数据,分为首数据和非首数据

if (head == NULL) {

head = input;

p = input;

} else {

while (p->next != NULL) {

p = p->next;

}

p->next = input;

}

//增加数据计数

(*total)++;

//询问是否继续

printf("\nDo you want to continue?(Y/N):");

scanf(" %c", &inputChar);

if (inputChar == 'Y' || inputChar == 'y') { //直接用getchar必须输入大写Y才能继续

//创建新的空间

input = (RECORD *) malloc(sizeof(RECORD));

i++;

} else {

break;

}

} while (1);

//将字符串后面的回车删除

AlterString(head);

return head;

}

//功能:打印全部数据

//入参:链表首地址,数据总数地址

//出参:无

void PrintAllRecords(RECORD *head, const int *total) {

int page = 1, firstIndex = 0, i, pageAmount = *total / 10 + 1;

RECORD *p = head;

do {

system("cls");

//处理输入的数字过大或过小

if (page > pageAmount) {

printf("-- Sorry! The MAX of pages is %d\n", pageAmount);

} else if (page < 0) {

printf("-- Sorry! The number have to be positive\n");

} else {

//处理分页

firstIndex = 10 * (page - 1);

printf("NO.\tName\tPhonenumber\tProvince\tCity\tStreet\tPostcode\t\n");

//处理前置数据

p = head;

for (i = 0; i < firstIndex; ++i) {

p = p->next;

}

i = 0;

//输出数据

while (p != NULL && i < 10) { //todo 大量数据可能出现问题

i++;

printf("NO.%d\t%s\t%s\t\t%s\t\t%s\t%s\t%s\t\n", i+firstIndex,p->name, p->phonenumber, p->address[0], p->address[1],

p->address[2],

p->postcode);

p = p->next;

}

printf("-- Page %d (Total %d pages)\n ", page, pageAmount);

}

printf("-- Jump to page number (Input 0 to finish):");

scanf("%d", &page);

} while (page);

}

//功能:删除某条数据

//入参:链表首地址

//出参:链表首地址

RECORD *DeleteRecord(RECORD *head,int *total) {

RECORD *p1 = head, *p2,*searchResult;

searchResult = SearchRecord(head, 1);

while (p1 != NULL && p1 != searchResult) {

p2 = p1; //p2上一个节点

p1 = p1->next; //p1下一个节点

}

if (p1 == head) {

head = p1->next;

free(p1);

(*total)--; //todo

printf("\n-- Success!\n");

} else if (p1 != NULL) {

p2->next = p1->next;

free(p1);

(*total)--;

printf("\n-- Success!\n");

} else {

printf("\n-- Do not find this id!\n");

}

return head;

}

//功能:输出某条数据

//入参:数据地址

//出参:无

void PrintOneRecord(RECORD *p) {

printf("Name:%s\tPhonenumber:%s\tProvince:%s\tCity:%s\tStreet::%s\tPostcode:%s\t\n", p->name, p->phonenumber,

p->address[0], p->address[1], p->address[2], p->postcode);

}

//功能:更改数据

//入参:数据地址

//出参:无

RECORD *ReviseRecord(RECORD *head){

RECORD *p1 = head, *p2,*searchResult,*input = (RECORD *) malloc(sizeof(RECORD));

//返回需要更改的数组地址

searchResult = SearchRecord(head, 1);

if (!searchResult){

return head;

}

//输入数据

printf("\nInput the newRecord`s Name:");

fflush(stdin);

fgets(input->name, CHARMAX + 1, stdin);

printf("Input the newRecord`s Phone Number:");

fflush(stdin);

fgets(input->phonenumber,CHARMAX + 1, stdin);

printf("Input the Record`s Address:\n");

printf("- Input the newRecord`s Province:");

fflush(stdin);

fgets(input->address[0], CHARMAX + 1, stdin);

printf("- Input the newRecord`s City:");

fflush(stdin);

fgets(input->address[1], CHARMAX + 1, stdin);

printf("- Input the newRecord`s Street:");

fflush(stdin);

fgets(input->address[2], CHARMAX + 1, stdin);

printf("- Input the newRecord`s Postcode:");

fflush(stdin);

fgets(input->postcode, 7, stdin);

//插入时放于链表的最后

input->next = NULL;

while (p1 != NULL && p1 != searchResult) {

p2 = p1; //p2上一个节点

p1 = p1->next; //p1下一个节点

}

if (p1 == head) {

head = input;

input->next = p1->next;

free(p1); //是否要释放?

printf("\n-- Success the Revise!\n");

} else if (p1 != NULL) {

p2->next = input;

input->next = p1->next;

free(p1);

printf("\n-- Success Revise!\n");

} else {

printf("\n-- Do not find this id!\n");

}

AlterString(head);

return head;

}

//功能:搜索数据,并返回唯一搜索结果

//入参:链表首地址,是否要求返回唯一结果

//出参:数据地址

RECORD *SearchRecord(RECORD *head, int onlyOneRecord) {

int amount = 0, i = 0, selection = 0; //i,p1循环变量

char input[CHARMAX];

RECORD *p1 = head, *results[100] = {NULL}; //result是RECORD类型的指针数组

printf("\n-- Search the record:");

setbuf(stdin, NULL);

fgets(input, CHARMAX + 1, stdin);

//去除字符串回车

for (i = 0; i < CHARMAX; ++i) {

if (*((input) + i) == '\n') {

*((input) + i) = '\0';

}

}

//遍历搜索

while (p1 != NULL) {

if (strstr(p1->name, input) || //strstr()判断是否为子串

strstr(p1->phonenumber, input) ||

strstr(p1->address[0], input) ||

strstr(p1->address[1], input) ||

strstr(p1->address[2], input) ||

strstr(p1->postcode, input)) {

results[amount] = p1;

amount++;

}

p1 = p1->next;

}

//若有多个结果,提示用户选择

if (amount > 1) {

printf("\n-- Search Result:\n");

for (i = 0; i < amount; i++) {

printf("NO.%d\t", i + 1);

PrintOneRecord(results[i]);

}

if (!onlyOneRecord) {

return NULL; //如果不需要去重,则返回NULL

}

printf("\n-- Input the number you want to change: ");

scanf("%d", &selection);

//处理输入数据不正确,默认返回第一个

if (selection - 1 > amount || selection < 0) {

printf("\n-- Wrong input (Choose the first record automatically)");

return results[0];

}

return results[selection - 1];

} else if (!amount) {

printf("\n-- Sorry! No result!");

return NULL;

} else {

printf("\n-- Search Result:\n");

PrintOneRecord(results[0]);

return results[0];

}

}

//功能:导入文件中的数据

//入参:链表首地址,总条数

//出参:数据地址

RECORD *ImportRecords(RECORD *head, int *total) {

int i = *total,m=3;

FILE *fpRead;

RECORD *p = head, *input;

fpRead = fopen("stu.txt","r");

if(fpRead==NULL){

printf("can't open file\n");

return 0;

}

do {

//输入数据

input = (RECORD *) malloc(sizeof(RECORD));

fread(input, sizeof(struct record),1,fpRead);

input->next = NULL; //插入时放于链表的最后

//插入数据,分为首数据和非首数据

if (head == NULL) {

head = input;

p = input;

} else {

while (p->next != NULL) {

p = p->next;

}

p->next = input;

}

//增加数据计数

(*total)++;

m--;

} while (m);

return head;

}

//功能:搜索数据,并返回唯一搜索结果

//入参:链表首地址,是否要求返回唯一结果

//出参:数据地址

RECORD *ExportRecords(RECORD *head){

FILE *fp;

struct record *p=head;

if((fp=fopen("stu.txt","wb"))==NULL)

{

printf("Fail to open the stu.txt!\n");

exit(0);

}

while(p != NULL)

{

fwrite(p, sizeof(struct record),1,fp);

p=p->next;

}

fclose(fp);

printf("you have save correctly!\n");

return 0;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值