C語言:實現一個通訊錄,可以進行增刪查改等多項功能(動態版本)
阿新 • • 發佈:2018-12-19
基於前一篇文章的靜態通訊錄,新增malloc函式,realloc函式以及free,將其改變為一個動態的通訊錄,可以動態記憶體開闢,儘可能防止記憶體的浪費。
具體程式碼如下:
contact.h
#ifndef __CONTACT_H__ #define __CONTACT_H__ #include <string.h> #include <stdlib.h> #include <stdio.h> #include <assert.h> #define NAME_MAX 20 #define SEX_MAX 5 #define TELE_MAX 12 #define ADDR_MAX 30 #define MAX 1000 #define DEFAULT_SZ 3 //定義人物資訊結構體 typedef struct PeoInfo { char name[NAME_MAX]; int age; char sex[SEX_MAX]; char tele[TELE_MAX]; char addr[ADDR_MAX]; }PeoInfo; ////定義通訊錄結構體(靜態版本) //typedef struct Contact //{ // PeoInfo date[MAX];//存放資料 // int sz;//當前已有資訊的個數 //}Contact,*pContact;//pContact就是一個結構體指標型別 //定義通訊錄結構體(動態版本) typedef struct Contact { PeoInfo * date;//指向一塊空間 int sz;//當前已有資訊的個數 int capacity; }Contact, *pContact;//pContact就是一個結構體指標型別 //函式宣告 void InitContact(pContact pc);//pContact=Contact* void AddContact(pContact pc); void ShowContact(pContact pc); void DelContact(pContact pc); void SearchContact(pContact pc); void ModifyContact(pContact pc); void SortContact(pContact pc); void EmptyContact(pContact pc); void DestroyContact(pContact pc); #endif //__CONTACT_H__
Contact.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "Contact.h" //初始化 void InitContact(pContact pc) { pc->sz = 0; pc->date = (PeoInfo*)malloc(DEFAULT_SZ * sizeof(PeoInfo)); pc->capacity = DEFAULT_SZ; } //銷燬通訊錄 void DestroyContact(pContact pc) { assert(pc); free(pc->date); pc->date = NULL; pc->capacity = 0; pc->sz = 0; } //檢查是否需要增容 void * check_capacity(pContact pc) { if (pc->capacity == pc->sz) { PeoInfo* tmp = realloc(pc->date, (pc->capacity + 2)*sizeof(PeoInfo)); if (tmp != NULL) { pc->date = tmp; pc->capacity += 2; printf("增容成功\n"); return pc->date; } else return NULL; } return pc->date; } void AddContact(pContact pc) { assert(pc); check_capacity(pc); printf("請輸入姓名:"); scanf("%s", pc->date[pc->sz].name); printf("請輸入年齡:"); scanf("%d", &(pc->date[pc->sz].age)); printf("請輸入性別:"); scanf("%s", pc->date[pc->sz].sex); printf("請輸入電話:"); scanf("%s", pc->date[pc->sz].tele); printf("請輸入地址:"); scanf("%s", pc->date[pc->sz].addr); pc->sz++; } void ShowContact(pContact pc) { assert(pc); int i = 0; printf("%10s\t%4s\t%5s\t%12s\t%20s\n", "name", "age", "sex", "tele", "addr"); for (i = 0; i < pc->sz; i++) { printf("%10s\t%4d\t%5s\t%12s\t%20s\n", pc->date[i].name, pc->date[i].age, pc->date[i].sex, pc->date[i].tele, pc->date[i].addr ); } } int FindEntry(pContact pc, char name[]) { assert(pc); int i = 0; for (i = 0; i < pc->sz; i++) { if (strcmp(pc->date[i].name, name) == 0) { return i; } } return -1;//沒找到 } void DelContact(pContact pc) { assert(pc); int i = 0; int j = 0; int pos = 0; char name[NAME_MAX] = { 0 }; printf("請輸入要刪除人的名字:"); scanf("%s", name); //查詢 pos = FindEntry(pc, name); //刪除 if (pos != -1) { for (j = pos; j < pc->sz - 1; j++) { pc->date[j] = pc->date[j + 1]; } pc->sz--; printf("刪除成功\n"); } else { printf("刪除的人不存在\n"); } } void SearchContact(pContact pc) { assert(pc); char name[NAME_MAX] = { 0 }; printf("請輸入要查詢人的名字:"); scanf("%s", name); int pos = 0; pos = FindEntry(pc, name); if (pos != -1) { printf("%10s\t%4s\t%5s\t%12s\t%20s\n", "name", "age", "sex", "tele", "addr"); printf("%10s\t%4d\t%5s\t%12s\t%20s\t\n", pc->date[pos].name, pc->date[pos].age, pc->date[pos].sex, pc->date[pos].tele, pc->date[pos].addr); } else { printf("要查詢的人不存在\n"); } } void ModifyContact(pContact pc) { assert(pc); char name[NAME_MAX] = { 0 }; printf("請輸入要修改人的名字:"); scanf("%s", name); //找 int pos = 0; pos = FindEntry(pc, name); if (pos != -1) { printf("請輸入姓名:"); scanf("%s", pc->date[pos].name); printf("請輸入年齡:"); scanf("%d", &(pc->date[pos].age)); printf("請輸入性別:"); scanf("%s", pc->date[pos].sex); printf("請輸入電話:"); scanf("%s", pc->date[pos].tele); printf("請輸入地址:"); scanf("%s", pc->date[pos].addr); printf("修改成功\n"); } else { printf("要修改的人不存在\n"); } } void SortContact(pContact pc) { assert(pc); int i = 0; int j = 0; int flag = 0; for (i = 0; i < pc->sz - 1; i++) { for (j = 0; j < pc->sz - 1 - i; j++) { if (strcmp(pc->date[j].name, pc->date[j + 1].name)>0) { PeoInfo tmp = pc->date[j]; pc->date[j] = pc->date[j + 1]; pc->date[j + 1] = tmp; flag = 1; } } if (flag == 0) { break; } } printf("按姓名排序成功\n"); } void EmptyContact(pContact pc) { pc->sz = 0; printf("通訊錄已清空\n"); }
test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include "Contact.h" void menu() { printf("***************************************\n"); printf("******** 1.add 2.del ********\n"); printf("******** 3.search 4.modify ********\n"); printf("******** 5.show 6.sort ********\n"); printf("******** 0.exit 7.empty ********\n"); printf("***************************************\n"); } enum Option//列舉可能取值,按照順序與menu裡的值對應 { EXIT, ADD, DEL, SEARCH, MODIFY, SHOW, SORT, EMPTY }; void test() { int input = 0; Contact con;//1000個任務資訊 + sz個數---通訊錄 InitContact(&con);//初始化通訊錄 do { menu(); printf("請選擇:"); scanf("%d", &input); switch (input) { case ADD: AddContact(&con);//1.傳地址效率高2.傳地址可以改變它 break; case DEL: DelContact(&con); break; case SEARCH: SearchContact(&con); break; case MODIFY: ModifyContact(&con); break; case SHOW: ShowContact(&con); break; case SORT: SortContact(&con); break; case EXIT: DestroyContact(&con); printf("退出通訊錄\n"); break; case EMPTY: EmptyContact(&con); default: printf("選擇錯誤\n"); break; } } while (input); } int main() { test(); return 0; }