C語言實現(xiàn)電話簿項目管理
本文實例為大家分享了C語言實現(xiàn)電話簿項目管理的具體代碼,供大家參考,具體內(nèi)容如下
1.前言
在C語言的學(xué)習(xí),經(jīng)常有一個需要完成的項目就是電話簿的管理,在剛學(xué)習(xí)玩C語言基本內(nèi)容后,面對這么多的項目需求往往無從下手,本文將一步一步完成電話簿的創(chuàng)建。本文提供一種思路,如有更好的實現(xiàn)歡迎討論。
2.實現(xiàn)功能
本電話簿需要實現(xiàn)的功能有
實現(xiàn)電話簿的初始創(chuàng)建
實現(xiàn)電話簿的后添加
實現(xiàn)電話簿的刪除
實現(xiàn)電話簿的查看(按鏈表的排序)
實現(xiàn)電話簿的查找(名字以及號碼)
實現(xiàn)電話簿的排序(名字以及號碼)
3.思路解析
3.1二級目錄實現(xiàn)電話簿的初始創(chuàng)建
創(chuàng)建電話簿需要知道要保存什么信息,這是用我們的結(jié)構(gòu)體來創(chuàng)建保存信息
typedef struct phone_book { char job[30];//工作信息 char number[20];//電話號碼 char name[15];//名字拼音 char email[30];//郵箱信息 struct phone_book* next;//指向下一個節(jié)點 }phone_book;
由于電話簿沒有限定有多大,并且是動態(tài)變化的,這時候用數(shù)組來保存信息顯然不合適,這時候就需要鏈表來實現(xiàn)。
在電話簿第一次運行時,里面沒有任何信息,我們需要來創(chuàng)建電話簿。我們需要三個指針來幫助我們解決問題。 其中一個是鏈表的頭指針,兩外兩個幫助我們開辟新的節(jié)點并指向下一個節(jié)點讓我們的鏈表接下去。
phone_book* head, * p1, * p2; head = NULL;//頭指針初始化為空 p1 = (phone_book*)malloc(LEN); p2 = p1;
完成指針的創(chuàng)建我們要輸入信息,就是下面這串代碼幫我們實現(xiàn),創(chuàng)建聯(lián)系人我不想一個一個輸入,就用一個循環(huán)讓它一直跑,直到名字輸入0結(jié)束。(沒有想到其他的好方法來結(jié)束欸~)
每輸入信息后要往鏈表里加入,用一個變量記錄聯(lián)系人數(shù)量,創(chuàng)建第一個是把它弄到頭指針里面去,后面的聯(lián)系人通過兩個指針處理接下去。
while (1) { printf("請輸入姓名(姓名為0時停止創(chuàng)建):"); gets_s(p1->name); if (strcmp(p1->name, "0") == 0) break; printf("請輸入電話號碼:"); gets_s(p1->number); printf("請輸入工作單位:"); gets_s(p1->job); printf("請輸入E-mail:"); gets_s(p1->email); n = n + 1; if (n == 1) head = p1; else p2->next = p1; p2 = p1; p1 = (phone_book*)malloc(LEN); }p2->next = NULL; return head;
3.2二級目錄實現(xiàn)電話簿的后添加
后添加的操作幾乎和創(chuàng)建一模一直,只是操作時為了方便把他們加到頭指針后面,所以這時候鏈表的排列并不是按照添加事件的順序了。(頭指針yyds)
3.3二級目錄實現(xiàn)電話簿的刪除
聯(lián)系人的刪除就有些難以理解了,不過也好理解。找到這個節(jié)點后,釋放它,在這之前要標(biāo)記它前一個節(jié)點后一個節(jié)點,讓它倆連接起來。直接上代碼。
通過查找我們發(fā)現(xiàn)要刪除節(jié)點p,如果要刪除的人正好在第一個,直接把頭指針接到后面,如果不是,就讓p1和p后面的節(jié)點相連,并且釋放p
phone_book* p = head, * p1;//p1是p的前一個節(jié)點 if (p == head) { head = p->next; free(p); } else { p1->next = p->next; free(p); }
3.4二級目錄實現(xiàn)電話簿的查找
只需要比較信息即可實現(xiàn),不過分為按名字和號碼來實現(xiàn),這就需要三個小函數(shù)來實現(xiàn)看代碼即可理解
3.5二級目錄實現(xiàn)電話簿的查找
只需要比較信息即可實現(xiàn),不過分為按名字和號碼來實現(xiàn),這就需要三個小函數(shù)來實現(xiàn)看代碼即可理解
3.6二級目錄實現(xiàn)電話簿的排序
只需要比較信息即可實現(xiàn),不過分為按名字和號碼來實現(xiàn),這就需要三個小函數(shù)來實現(xiàn)看代碼即可理解
4.源代碼及注釋
#define _CRT_SECURE_NO_WARNINGS #include<string.h> #include<stdio.h> #include<stdlib.h> #include<malloc.h> typedef struct phone_book { char job[30]; char number[20]; char name[15]; char email[30]; struct phone_book* next; }phone_book; #define LEN sizeof(phone_book) phone_book* creat_list() { phone_book* head, * p1, * p2; char name[15]; int n = 0; head = NULL; p1 = (phone_book*)malloc(LEN); p2 = p1; while (1) { printf("請輸入姓名(姓名為0時停止創(chuàng)建):"); gets_s(p1->name); if (strcmp(p1->name, "0") == 0) break; printf("請輸入電話號碼:"); gets_s(p1->number); printf("請輸入工作單位:"); gets_s(p1->job); printf("請輸入E-mail:"); gets_s(p1->email); n = n + 1; if (n == 1) head = p1; else p2->next = p1; p2 = p1; p1 = (phone_book*)malloc(LEN); }p2->next = NULL; return head; }//鏈表創(chuàng)建函數(shù) void print_list(phone_book* head) { void menu(); int n = 0; printf("現(xiàn)在通訊錄中有如下成員:"); while (head != NULL) { printf("\n名字:"); puts(head->name); printf("\n電話號碼:"); puts(head->number); printf("\n工作單位:"); puts(head->job); printf("\nE-mail:"); puts(head->email); putchar('\n'); head = head->next; n++; if (n % 8 == 0) { printf("按回車鍵顯示下一頁"); getchar(); system("cls"); menu(); } } printf("總共%d個聯(lián)系人\n", n); } int length(phone_book* head) { int n = 0; phone_book* p; p = head; while (p != NULL) { p = p->next; n++; } return n; }//判斷聯(lián)系人個數(shù) void sortbynumber(phone_book* head) { void menu(); int n = length(head); int i, j; phone_book temp, * p; p = head; phone_book a[1000]; for (i = 1; i <= n; i++) { strcpy(a[i].name, p->name); strcpy(a[i].number, p->number); strcpy(a[i].job, p->job); strcpy(a[i].email, p->email); p = p->next; } for (i = 1; i <= n - 1; i++) { for (j = 1; j <= n - i; j++) { if (strcmp(a[j].number, a[j + 1].number) > 0) { temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } } } printf("現(xiàn)在通訊錄中有如下成員:"); for (i = 1; i <= n; i++) { printf("\n名字:"); puts(a[i].name); printf("\n電話號碼:"); puts(a[i].number); printf("\n工作單位:"); puts(a[i].job); printf("\nE-mail:"); puts(a[i].email); putchar('\n'); if (i % 8 == 0) { printf("按回車鍵顯示下一頁"); getchar(); system("cls"); menu(); } } printf("總共%d個聯(lián)系人\n", n); } void sortbyname(phone_book* head) { void menu(); int n = length(head); int i, j; phone_book temp, * p; p = head; phone_book a[100]; for (i = 1; i <= n; i++) { strcpy(a[i].name, p->name); strcpy(a[i].number, p->number); strcpy(a[i].job, p->job); strcpy(a[i].email, p->email); p = p->next; } for (i = 1; i <= n - 1; i++) { for (j = 1; j <= n - i; j++) { if (strcmp(a[j].name, a[j + 1].name) > 0) { temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } } } printf("現(xiàn)在通訊錄中有如下成員:"); for (i = 1; i <= n; i++) { printf("\n名字:"); puts(a[i].name); printf("\n電話號碼:"); puts(a[i].number); printf("\n工作單位:"); puts(a[i].job); printf("\nE-mail:"); puts(a[i].email); putchar('\n'); if (i % 8 == 0) { printf("按回車鍵顯示下一頁"); getchar(); system("cls"); menu(); } } printf("總共%d個聯(lián)系人\n", n); }//排序按照電話號碼 void sort_list(phone_book* head) { void menu(); if (head == NULL) { printf("電話簿為空,請重新創(chuàng)建!"); return; } char a; printf("1,按電話號碼升序排序\n2,按姓名字母升序排序\n"); printf("請選擇一種排序方法:"); a = getchar(); getchar(); switch (a) { case'1':sortbynumber(head); break; case'2':sortbyname(head); break; default:printf("輸入有誤!\n"); break; } } void findbyname(phone_book* head) { if (head == NULL) { printf("電話簿為空,請重新創(chuàng)建"); return; } char name[15]; printf("請輸入名字:"); gets_s(name); while (strcmp(name, head->name) != 0) { head = head->next; if (head == NULL) { printf("電話簿未有此聯(lián)系人\n"); return; } } printf("%s的電話號碼為:", name); puts(head->number); printf("\n工作單位:"); puts(head->job); printf("\nE-mail:"); puts(head->email); } void findbynumber(phone_book* head) { if (head == NULL) { printf("電話簿為空,請重新創(chuàng)建"); return; } char number[20]; printf("請輸入電話號碼:"); gets_s(number); while (strcmp(number, head->number) != 0) { head = head->next; if (head == NULL) { printf("電話簿未有此聯(lián)系人\n"); return; } } printf("%s的主人為:", number); puts(head->name); printf("\n工作單位:"); puts(head->job); printf("\nE-mail:"); puts(head->email); } void find(phone_book* head) { int n; printf(" 1,通過名字查找\n 2,通過電話號碼查找\n 3,退出\n請選擇你需要的服務(wù):"); scanf("%d", &n); getchar(); while (1) { if (n == 1) { findbyname(head); printf("請選擇服務(wù)項:"); scanf("%d", &n); getchar(); } if (n == 2) { findbynumber(head); printf("請選擇服務(wù)項:"); scanf("%d", &n); getchar(); } if (n == 3) return; else { printf("輸入不正確!"); printf("請選擇服務(wù)項:"); scanf("%d", &n); getchar(); } } }//查找聯(lián)系人 void add_list(phone_book* head) { phone_book* p1, * p2, * h; h = NULL; char name[15]; p1 = (phone_book*)malloc(LEN); p2 = p1; int n = 0; while (1) { printf("請輸入名字(名字為0時停止)"); gets_s(p1->name); if (strcmp(p1->name, "0") == 0)break; printf("請輸入電話號碼:"); gets_s(p1->number); printf("請輸入工作單位:"); gets_s(p1->job); printf("請輸入E-mail:"); gets_s(p1->email); n = n + 1; if (n == 1) h = p1; else p2->next = p1; p2 = p1; p1 = (phone_book*)malloc(LEN); } p1 = head->next; head->next = h; p2->next = p1; }//添加鏈表函數(shù) phone_book* delete_list(phone_book* head) { char a[20]; printf("請輸入聯(lián)系人名字或電話:"); gets_s(a); if (head == NULL) { printf("電話簿為空,請重新創(chuàng)建"); return head; } phone_book* p = head, * p1; p1 = NULL; while (strcmp(a, p->name) != 0 && strcmp(a, p->number) != 0) { p1 = p; p = p->next; if (p == NULL) { printf("電話簿未有此聯(lián)系人\n"); return head; } } printf("查找到了!"); printf("\n名字:"); puts(p->name); printf("\n電話號碼:"); puts(p->number); printf("\n工作單位:"); puts(p->job); printf("\nE-mail:"); puts(p->email); putchar('\n'); char b[10]; printf("是否刪除該聯(lián)系人(Y/N)"); gets_s(b); if (strcmp(b, "y") == 0 || strcmp(b, "Y") == 0) { if (p == head) { head = p->next; free(p); } else { p1->next = p->next; free(p); } printf("成功刪除!"); } else if (strcmp(b, "n") == 0 || strcmp(b, "N") == 0) printf("取消刪除!"); else printf("輸入錯誤!"); return head; }//刪除鏈表函數(shù) void save_list(phone_book* head) { FILE* fp; if ((fp = fopen("dianhuabu.dat", "wb")) == NULL) { printf("File cannot be opened\n"); exit(0); } if (head == NULL) { printf("通訊錄為空\n"); return; } phone_book* p1 = head; while (p1 != NULL) { if (fwrite(p1, LEN, 1, fp) != 1) { printf("cannot open file\n"); return; } p1 = p1->next; } printf("保存完畢!\n"); fclose(fp); }//文件寫入函數(shù) phone_book* load_list(phone_book* head) { FILE* fp; if ((fp = fopen("dianhuabu.dat", "rb")) == NULL) { printf("電話簿為空,請重新創(chuàng)建\n"); exit(0); }phone_book* p1, * p2; p1 = (phone_book*)malloc(LEN); if (fread(p1, LEN, 1, fp) == 0) { printf("電話簿為空,請重新創(chuàng)建"); return head; } head = p1; p2 = p1; p1 = (phone_book*)malloc(LEN); while (fread(p1, LEN, 1, fp)) { p2->next = p1; p2 = p1; p1 = (phone_book*)malloc(LEN); } p2->next = NULL; free(p1); return(head); fclose(fp); }//文件讀取函數(shù) void menu() { printf(" 歡迎進入電話簿系統(tǒng) \n"); printf("********************************************\n"); printf(" 1、創(chuàng)建電話簿(會將原有電話簿覆蓋)\n"); printf(" 2、查找聯(lián)系人 \n"); printf(" 3、添加聯(lián)系人 \n"); printf(" 4、刪除聯(lián)系人 \n"); printf(" 5、顯示聯(lián)系人 \n"); printf(" 6、查看電話簿(排序) \n"); printf(" 7、退出系統(tǒng) \n"); printf("********************************************\n"); }//菜單界面 void main() { system("cls"); menu();//進入菜單界面 printf(" 請選擇你所需要的服務(wù):"); int n; scanf("%d", &n); getchar(); phone_book* head; head = NULL; while (1) { system("cls"); menu(); switch (n) { case 1: { head = creat_list(); system("cls"); menu(); print_list(head); save_list(head); printf("********************************************\n"); printf("\n如需要其他服務(wù),請重新輸入:"); scanf("%d", &n); getchar(); }break;//創(chuàng)建電話簿(創(chuàng)建鏈表、寫入文件,釋放鏈表) case 2: { head = load_list(head); find(head); printf("********************************************\n"); printf("\n如需要其他服務(wù),請重新輸入:"); scanf("%d", &n); getchar(); }break;//查找聯(lián)系人(讀入文件、查找函數(shù)、釋放鏈表) case 3: { head = load_list(head); add_list(head); system("cls"); menu(); save_list(head); printf("********************************************\n"); printf("\n如需要其他服務(wù),請重新輸入:"); scanf("%d", &n); getchar(); }break;//添加聯(lián)系人(讀入文件、添加鏈表、寫入文件、釋放鏈表) case 4: { head = load_list(head); head = delete_list(head); save_list(head); printf("********************************************\n"); printf("\n如需要其他服務(wù),請重新輸入:"); scanf("%d", &n); getchar(); }break;//刪除聯(lián)系人(讀入文件,刪除鏈表、寫入文件、釋放鏈表) case 5: { head = load_list(head); print_list(head); save_list(head); } case 6: { head = load_list(head); sort_list(head); printf("********************************************\n"); printf("\n如需要其他服務(wù),請重新輸入:"); scanf("%d", &n); getchar(); }break;//查看電話簿(讀入文件,排序鏈表、釋放鏈表) case 7: { system("cls"); return; }break;//退出 default: { printf("\n輸入有誤,請重新輸入:"); scanf("%d", &n); getchar(); }break; } } }
5結(jié)束語
以上就是電話簿管理完全過程,歡迎探討。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C語言實現(xiàn)古代時辰計時與現(xiàn)代時間換算
這篇文章主要為大家詳細(xì)介紹了如何利用C語言實現(xiàn)古代時辰計時與現(xiàn)代時間換算,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2023-03-03詳解C++設(shè)計模式編程中策略模式的優(yōu)缺點及實現(xiàn)
這篇文章主要介紹了C++設(shè)計模式編程中策略模式的優(yōu)缺點及實現(xiàn),文中討論了策略模式中設(shè)計抽象接口的繼承和組合之間的區(qū)別,需要的朋友可以參考下2016-03-03C語言中關(guān)于動態(tài)內(nèi)存分配的詳解
動態(tài)內(nèi)存是指在堆上分配的內(nèi)存,而靜態(tài)內(nèi)存是指在棧上分配的內(nèi)存。棧上分配的內(nèi)存是由系統(tǒng)分配和釋放的,空間有限,在復(fù)合語句或函數(shù)運行結(jié)束后就會被系統(tǒng)自動釋放而堆上分配的內(nèi)存則不會有這個問題。2021-09-09