雙向迴圈鏈表(C語言描述)(四)

來源:互聯網
上載者:User

標籤:傳遞   location   length   word   odi   清空   linux   存在   scanf   

  下面以一個電子英漢詞典程式(以下簡稱電子詞典)為例,應用雙向迴圈鏈表。分離資料結構,可以使邏輯代碼獨立於資料結構作業碼,程式結構更清晰,代碼更簡潔;電子詞典的增、刪、查、改操作分別對應於鏈表的插入、刪除、尋找、尋找和擷取鏈表元素操作。

  在程式初始化時,除了初始化鏈表,還要將儲存在檔案中的詞庫載入到鏈表中:

1 void dict_init() {2     list = linkedlist_new();3 4     dict_load();5     printf("Welcome.");6 }

函數dict_load()實現如下:

 1 static void dict_load() { 2     FILE * fp; 3     struct Word word; 4  5     while (!(fp = fopen(PATH, "rb"))) { 6         fp = fopen(PATH, "wb"); 7         fclose(fp); 8     } 9     assert(fp);10 11     fread(&word, sizeof(struct Word), 1, fp);12     while (!feof(fp)) {13         linkedlist_insert(list, TRAVELDIR_BACKWARD, 1, word);14         fread(&word, sizeof(struct Word), 1, fp);15     }16 17     fclose(fp);18 }

函數feof()應先讀後判斷,所以在進入迴圈之前應先讀一次。

  當然,在程式結束前,也要將鏈表中的片語儲存到檔案中,函數dict_store()實現如下:

 1 static void dict_store() { 2     FILE * fp; 3     const int count = linkedlist_length(list); 4  5     assert(fp = fopen(PATH, "wb")); 6     for (int i = 0; i < count; i++) { 7         fwrite(linkedlist_get(list, TRAVELDIR_FORWARD, i + 1), 8                 sizeof(struct Word), 1, fp); 9     }10 11     fclose(fp);12 }

   一個英漢片語包含一個英文,一個中文,可以把它定義為一個結構體,並讓它作為鏈表節點資料域的資料類型;修改linkedlist.h中LinkedlistData的相關定義:

1 typedef struct Word {2     string eng;3     string chn;4 } LinkedListData;

C語言中沒有string類型,可以使用定長的字元數組來定義它;再定義一個函數mygets()用來代替scanf()函數,以確保輸入的內容不會超出緩衝區:

 1 #define MAX_STR_LEN 8 2 typedef char string[MAX_STR_LEN]; 3  4 void mygets(char * s) 5 { 6     __fpurge(stdin); 7     fgets(s, MAX_STR_LEN, stdin); 8     while (*s++) { 9         *s = *s == ‘\n‘ ? 0 : *s;10     }11 }

在Linux下,使用__fpurge()函數來代替Windows下的fflush()函數清空輸入資料流。

   接下來就是電子詞典的增、刪、查、改操作:

 1 void dict_add(const char * eng) { 2     struct Word word; 3     strcpy(word.eng, eng); 4  5     printf("The word does not exist, add it?\ny/n>"); 6     if (__fpurge(stdin), getchar() == ‘y‘) { 7         printf("Ok, what does it mean?\n>"); 8         mygets(word.chn); 9 10         linkedlist_insert(list, TRAVELDIR_BACKWARD, 1, word);11         printf("The word is existed now.\n");12     }13 }14 15 void dict_delete() {16     int location;17     struct Word word;18 19     printf("What word do you wanna delete?\n>");20     mygets(word.eng);21 22     if ((location = linkedlist_locate(list, TRAVELDIR_FORWARD, word, dict_cmp))23             != -1) {    // found24         struct Word * pWord = linkedlist_get(list, TRAVELDIR_FORWARD, location);25 26         printf("Delete: %s %s\nAre you sure?\ny/n>", pWord->eng, pWord->chn);27         if (__fpurge(stdin), getchar() == ‘y‘) {28             linkedlist_delete(list, TRAVELDIR_FORWARD, location);29             printf("The word is deleted now.\n");30         }31     } else {            // not found32         printf("The word does not exist.\n");33     }34 }35 36 void dict_search(const char * eng) {37     int location;38     struct Word word;39     strcpy(word.eng, eng);40 41     if ((location = linkedlist_locate(list, TRAVELDIR_FORWARD, word, dict_cmp))42             == -1) {    // not found43         dict_add(eng);44     } else {            // found45         printf("%s\n", linkedlist_get(list, TRAVELDIR_FORWARD, location)->chn);46     }47 }48 49 void dict_modify() {50     int location;51     struct Word word;52 53     printf("What word do you wanna modify?\n>");54     mygets(word.eng);55 56     if ((location = linkedlist_locate(list, TRAVELDIR_FORWARD, word, dict_cmp))57             != -1) {    // found58         struct Word * pWord = linkedlist_get(list, TRAVELDIR_FORWARD, location);59 60         printf("Ok, what does it mean?\n>");61         mygets(pWord->chn);62         printf("The word is modified now.\n");63     } else {            // not found64         printf("The word does not exist.\n");65     }66 }

dict_cmp()函數作為參數傳遞給linkedlist_locate()函數,用以比較片語是否相同,相同則返回0,它的實現如下:

1 int dict_cmp(const void * s1, const void * s2) {2     return strcmp(((LinkedListData *) s1)->eng, ((LinkedListData *) s2)->eng);3 }

還需要一個函數來組織這些子函數的調用:

 1 void dict_show() { 2     while (1) { 3         string str; 4         printf("\n>"); 5         mygets(str); 6  7         if (!strcmp(str, "quit;")) { 8             dict_store(); 9             linkedlist_destory(&list);10             printf("Bye.\n");11             return;12         } else if (!strcmp(str, "delete;")) {13             dict_delete();14         } else if (!strcmp(str, "modify;")) {15             dict_modify();16         } else {17             dict_search(str);18         }19     }20 }

  最後,編寫主函數,電子詞典就大功告成了!

雙向迴圈鏈表(C語言描述)(四)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.