作為此學期的一個作業:
一種簡單的英文單詞排版系統實現 一、功能 英文單詞排版及查詢系統基本功能(大小寫敏感):錄入單詞和釋義、修改單詞、修改釋義、文件錄入、輸出到屏幕和輸出到文件、輸入單詞查詢已有釋義。 二、實現約定 1、單詞結構 typedef struct dictWord { char word[101]; char meaning[201]; } DictWord; 2、錄入單詞和釋義 錄入規則: A) 一行只能錄入一個單詞或詞組和釋義, B) 可以只錄入單詞 C) 每一次錄入得單詞總長度包含空格不超過100字符 D) 不能只錄入釋義 E) 單詞和釋義之間必須有空格 F) 單詞是連續的或有空格的字母,不能有其他字符 G) 錄入異常打印對應的錯誤信息。 H) 錄入時單詞已經存在且釋義不同,則視為修改釋義,增加修改計數 I) 釋義應只包含漢字、阿拉伯數字和漢字標點符號且長度不超過100字 3、修改單詞 修改規則: A) 修改的關鍵字是”<<”,修改示例:worr << word B) << 必須在兩個單詞的中間,且和前后單詞有空格隔開 C) 修改錯誤打印錯誤信息 D) 單詞應僅包含空格和字母,不能有其他字符 4、修改釋義 修改釋義同2 5、文件錄入 文件錄入規則: A) 錄入時輸入相對文件名或者絕對文件名 B) 文件名只能是英文和‘/’,其他字符視為輸入錯誤。 C) 文件名輸入錯誤或者未找到文件名打印對應的錯誤信息 D) 文件內單詞規則(一行錄入一個單詞和單詞的釋義):單詞 釋義\n E) 錄入時單詞已經存在且釋義不同,則視為修改釋義,增加修改計數 F) 錄入時單詞和釋義都相同,視為錄入成功,增加單詞相同的計數 G) 錄入時單詞不存在,則錄入,增加錄入成功計數 H) 錄入完成時打印總單詞數目、錄入成功目、單詞相同的數據和修改數目 6、屏幕輸出 輸出規則: A) 按照字母序排序輸出 7、文件輸出 文件輸出規則: A) 按照字母序排序輸出 B) 輸入需要保存的文件名,文件名是相對文件名或者絕對文件名(只能是英文字母和’/’) 8、使用命令提示符 A) 使用兩個連續的右尖括號作為命令提示符 >> 來表明后面是一條命令而不是一個單詞 例:>>menu 將回到菜單; C) 每一次輸入只能錄入 查詢 或執行一條命令 所以, 下面這個例子, >>menu word 將轉到菜單並忽略后面的word >>menuword 將打印如下錯誤信息“無法識別的指令” D) 使用>>help 打印幫助信息 E) 命令不區分大小寫 F) 您可以使用的命令有; i. H 打印幫助 ii. M 顯示菜單 iii. FF 從文件錄入 iv. << 修改單詞,用法 A << B 將A 修改為B ,釋義保持不變 該命令可單獨使用,不需要提示符 >> v. View [-t] 該命令用來以t秒間隔連續打印已有數據的單詞及其對應釋義。 T默認為0. 按任意鍵退出該模式。 vi. BB 進入連續錄入模式 改模式下,你可以連續從屏幕輸入以錄入單詞。錄入規則如下: 1. 單詞在前,注釋在后,單詞與注釋間用空格分隔,每一個單詞或詞組總長度不超過100字,空格占用一字符。 2. 單詞應只包含空格及字母,包含其他字符將被認定為釋義部分 3. 注釋只能以漢字或阿拉伯數字開頭,總長度限制在200字,標點符號和數字占用一個字。 4. 每輸入完一次回車以進行下一次錄入 5. 一次只能輸入一個單詞或詞組及其對應釋義 6. 錄入模式下可使用提示符>> 進行操作 二、功能實現 A) 主函數調用menu顯示菜單,初始化參數,然后調用輸入函數,傳入保存單詞和釋義的數組參數,並等待用戶輸入 B) 輸入函數 1、輸入函數從屏幕讀取並分析是否包含命令提示符>> ,然后判斷當前所屬模式, I、默認模式將輸入單詞存入單詞數組,遇到非法字符或換行符結束。完成返回0 Ii、錄入模式將輸入單詞,和釋義存入相應數組,釋義為空則忽略,完成返回0 Iii、如果開頭包含命令提示符,包含命令提示符,則錄入后面的命令及其參數,並返回主函數對應命令的相應值。 Iiii、輸入函數會自動忽略開頭空格,並刪除輸入字符之間多余空格,輸入 C) 排序函數 D) 寫入文件函數 E) 順序輸出函數 F) 查詢函數
簡單字典使用手冊 一、 功能 1、英文單詞排版及查詢系統基本功能:錄入單詞和釋義、修改單詞/釋義、文件錄入、輸出到屏幕和輸出到文件、查詢釋義。 二、實現約定 1、通用約定 按照終端提示輸入,即可正常使用該軟件 單詞是由連續的字母組成,且大小寫敏感,長度不大於50 文件名可以是相對文件名和絕對文件名,文件名只能有字母和’/’組成 回車代表輸入完成,把輸入數據交給程序執行 特定模式下輸入字符’q’,退出當前模式 命令模式提示符”$”,二級模式提示符:”>>” 輸入不符合約定會打印錯誤信息 2、關鍵字約定 1、search:進入單詞搜索模式 2、enter:錄入單詞和釋義 3、update:修改單詞或者釋義 4、file:從文件錄入 5、output:輸出到屏幕 6、outfile:輸出到文件 7、help:輸出命令關鍵字和含義 3、命令概述 搜索模式 A) 命令模式輸入命令”search”進入查詢模式 B) 輸入單詞 回車 C) 打印單詞釋義 錄入單詞和釋義: A) 命令模式輸入命令”enter”進入單詞和釋義的錄入 B) 一行只能錄入一個單詞和釋義,可以只錄入單詞,不能只錄入釋義、單詞和釋義之間必須至少有一個空格 修改單詞和釋義: A) 命令模式輸入命令”update”,進入修改模式 B) 輸入要更新的單詞 C) 輸入修改后的單詞和釋義(同錄入) 文件錄入: A) 文件錄入模式輸入命令” file”,進入文件錄入模式 B) 輸入文件名 C) 文件內單詞規則:同錄入 D) 單詞已經存在且釋義不同,則視為修改釋義,增加修改計數 E) 錄入時單詞和釋義都相同,視為錄入成功,增加單詞相同計數 F) 錄入時單詞不存在,則錄入,增加成功計數 G) 錄入時單詞不符合規則,增加錯誤記錄 H) 錄入完成時打印總單詞數目、錄入成功計數、修改計數、單詞相同計數和錯誤計數。 屏幕輸出 A) 命令模式輸入命令”output”,進入屏幕輸出模式 B) 輸出打印規則,輸入數字表示打印多少個單詞和釋義 文件輸出 A) 命令模式輸入命令” outfile”,進入屏幕輸出模式 B) 輸入文件名
#include "main.h" /***** 全局變量 ***************/ char beauty[600]; char DictFile[200]; /**** 全局變量END ************/ struct wtree root; extern int getAndCheckWord(char *pWord,char *exp);//0是返回命令 -1錯誤 1返回單詞 2替換單詞 -2未知錯誤*/ void clean_Print( const char *str ); /**** 清空緩存函數*/ void lprint(); void temprint(); void strprint(char str[],int t); void miniDict(); void Menu(); int checkCmd( int opt ); int getOption( char str[] ) ; int cmdHelp(); int cmdCls(); int cmdMenu() ; int fun_search(); int searchAndReplaceWord(char w[],char r[],struct wtree *pt); int fun_enter(); int fun_ffile(); int getOption_ffile( char str[]); int get_from_file(FILE *fp, char *pWord,char *exp );/**** 輸入函數 -1錯誤 1返回單詞 -2未知錯誤*/ int fun_ofile(); int fun_outprint(); int fun_help(); int word_tree_traveal(struct wtree* pt,char *str,FILE *fp); bool word_tree_delete(char *str,struct wtree *pt); bool word_tree_child_enum(struct wtree* pt); struct wtree* word_tree_search(char *str,struct wtree *pt); struct wtree* word_tree_insert(char *str,char *exp,struct wtree *pt); struct wtree* creatchild(); int alpcompare(const char a,const char b); int ptlen(struct wtree* pt[]); int exchange(char str[]); char DictFile[200]; int main(int argc, char *argv[]) { #ifdef _WIN32 SetConsoleTitle("MiniDict"); system("mode con cols=80 lines=50"); system("color B0"); #endif //__WIN32 temprint(); strcpy(DictFile,"minidict.mi"); // printf("E%sE",DictFile); strprint(beauty, 2); if (access(DictFile,F_OK) == 0) { strcpy(cmdOption,DictFile); load_file(); cmdOption[0] = '\0'; } system( "cls" ); miniDict(); Menu(); fun_tip = help; while(1) { switch (fun_tip) { case help: fun_help(); fun_tip = search; break; case search: fun_search(); break; case enter: fun_enter(); break; case ffile: fun_ffile(); break; case ofile: fun_ofile(); break; // case info: // fun_info(); // break; case outprint: fun_outprint(); break; } } return(0); } int load_file() { samewords = 0; int coun = 0; printf("loading from file...please wait ...\n"); FILE *read; char word[WORD_NUMBER] = {0}; char wordExp[EXP_NUMBER] = {0}; int flag; read = fopen(cmdOption,"r"); if (read == NULL) { printf("open file error!\n"); fun_tip = search; return 0; } else { while (1) { flag = get_from_file(read,word,wordExp); if (flag == -1) { //printf("This word will be ignore\n"); continue; } else if (flag == 1) { char tempword[WORD_NUMBER]; printf("%s",tempword); strcpy(tempword,word); exchange(tempword); word_tree_insert(tempword,wordExp,&root); coun++; printf("%s\n",word); continue; } else if (flag == 0) { if( fclose(read) != 0) { perror("fclosed"); } return 0; } } } }
/************************************************************************* > File Name: main.h > Author: > Mail: > Created Time: Thu 30 Jan 2020 06:50:54 AM HKT ************************************************************************/ #ifndef _AJA_H #define _AJA_H #define DEF_SLEEP_TIMES 5 #define ERRORMESSAGE_LENTH 30 #ifndef TRUE #define FALSE 0 #define TRUE 1 #endif // TRUE #if _WIN32 #include <dos.h> #include <windows.h> #else #include <unistd.h> #endif // _linux_ #include <stdbool.h> #include "common.h" #include "wtree.h" #include "func.h" extern int load_file(); #endif
#include "wtree.h" static struct wtree defstr; int samewords; char TempFile[200] = "minidicttemp"; static struct wtree *creatchild(void) { struct wtree *p = (struct wtree *)malloc(sizeof(struct wtree)); if (p == NULL) { printf("Error,out of memory!\n"); return NULL; } *p = defstr; return p; } int word_tree_traveal_delete(struct wtree* pt) { int i = 0; while (1) { if (pt->child[i] == NULL) { return 0; } else if (pt->child[i] != NULL) { word_tree_traveal_delete(pt->child[i]); free(pt->child[i]); pt->child[i] = NULL; i++; continue; } } } int word_tree_traveal(struct wtree* pt,char *str,FILE *fp) { int i = 0; int flag = 0; if (fp == NULL) { FILE *fp1 = fopen(TempFile,"w"); if (fp1 == NULL) { printf("Failed, insufficient permissions\n"); return -1; } flag = 1; fp = fp1; } if (str == NULL) { char str1[WORD_NUMBER]; if (str1 == NULL) { printf("Failed\n"); return -1; } str = str1; str[0] = '\0'; flag = 1; } int j = strlen(str); int len = ptlen(pt->child); //printf("pt %d\n%d",len,strlen(pt->child)); while (i < len) { // printf("%s\ni = %d\nj = %d\n",str,i,j); if (pt->child[i] == NULL) { break; } else if (pt->child[i] != NULL) { str[j] = (pt->child[i])->c; str[j + 1] = '\0'; if ((pt->child[i])->self == TRUE) { fputs(str,fp); if (strlen((pt->child[i])->exp) == 0 ) { fputs("\n",fp); } else { fputs(" ",fp); fputs((pt->child[i])->exp,fp); fputs("\n",fp); } } if(word_tree_traveal(pt->child[i],str,fp) == -1) { return -1; } else { i++; continue; } } } if (flag == 1 && i == (len - 1)) fclose(fp); return 0; } bool word_tree_child_enum(struct wtree* pt) { int i; int len = ptlen(pt->child); if (len == 0) { return FALSE; } else { for (i = 0; i < len; i++) { if (pt->child[i] != NULL) { return TRUE; } } return FALSE; } } bool word_tree_delete(char *str,struct wtree *pt) { int len = strlen(str); int i = 0; while (1) { if (pt->child[i] == NULL) { return FALSE; } else if(alpcompare((pt->child[i])->c,str[len - 1]) < 0) /**** a < b **/ { i++; continue; } else if (alpcompare((pt->child[i])->c,str[len - 1]) == 0) { str[len - 1] = '\0'; if (len == 1) { if ((pt->child[i])->self == TRUE) { (pt->child[i])->self = NULL; (pt->child[i])->exp[0] = '\0'; } break; } else { word_tree_delete(str,pt->child[i]); break; } } else if (alpcompare((pt->child[i])->c,str[len - 1]) > 0) { return FALSE; } } if (!word_tree_child_enum(pt->child[i])) /****無用節點刪除 ***/ { int templen1 = ptlen(pt->child); for (free(pt->child[i]); i < templen1 - 2; i++) { pt->child[i] = pt->child[i + 1]; } pt->child[templen1 - 1] = NULL; } return TRUE; } struct wtree* word_tree_search(char *str,struct wtree *pt) { int len = strlen(str); int i = 0; while (1) { if (pt->child[i] == NULL) { return NULL; } else if (alpcompare((pt->child[i])->c,str[len - 1]) < 0) /**** a < b **/ { i++; continue; } else if (alpcompare((pt->child[i])->c,str[len - 1]) == 0) { str[len - 1] = '\0'; if (len == 1) { return (pt->child[i]); } else { return word_tree_search(str,pt->child[i]); } } else if (alpcompare((pt->child[i])->c,str[len - 1]) > 0) { return NULL; } } } struct wtree* word_tree_insert(char *str,char *exp,struct wtree *pt) { int len = strlen(str); if (len == 0) { printf("沒有什么需要插入的!\n"); return NULL; } int i = 0; while (1) { if (pt->child[i] == NULL) { pt->child[i] = creatchild(); *(pt->child[i]) = defstr; (pt->child[i])->c = str[len - 1]; str[len - 1] = '\0'; if (len == 1) { strcpy((pt->child[i])->exp,exp); (pt->child[i])->self = TRUE; //printf("return %p",pt->child[i]); return (pt->child[i]); } else { return word_tree_insert(str,exp,pt->child[i]); } } else if (alpcompare((pt->child[i])->c,str[len - 1]) < 0) /**** a < b **/ { i++; continue; } else if (alpcompare((pt->child[i])->c,str[len - 1]) == 0) { str[len - 1] = '\0'; if (len == 1) { samewords++; strcpy((pt->child[i])->exp,exp); (pt->child[i])->self = TRUE; return (pt->child[i]); } else { return word_tree_insert(str,exp,pt->child[i]); } } else if (alpcompare((pt->child[i])->c,str[len - 1]) > 0) { int tempint; int templen = ptlen(pt->child); for (tempint = templen - 1; tempint > i; tempint--) { pt->child[tempint] = pt->child[tempint - 1]; } pt->child[i] = creatchild(); (pt->child[i])->c = str[len - 1]; str[len - 1] = '\0'; if (len == 1) { strcpy((pt->child[i])->exp,exp); (pt->child[i])->self = TRUE; return (pt->child[i]); } else { return word_tree_insert(str,exp,pt->child[i]); } } } } int alpcompare(const char a,const char b) { if (toupper(a) == toupper(b)) { if (a == b) { return 0; } else if (a > b) /***** A isLOWER ********/ { return 1; } else if (a < b) { return -1; } else if (a == b) { return 0; } } else if (toupper(a) != toupper(b)) { return (toupper(a) - toupper(b)); } return 0; } int ptlen(struct wtree* pt[]) { int i = 0; while (pt[i] != NULL) i++; return i + 1; } int exchange(char str[]) { int left = 0; int right = strlen(str) - 1; char temp; while(1) { if ( left <= right) { temp = str[left]; str[left++] = str[right] ; str[right--] = temp; } else { break; } } return 0; }
/************************************************************************* > File Name: wtree.h > Author: > Mail: > Created Time: Thu 30 Jan 2020 07:25:31 AM HKT ************************************************************************/ #ifndef _WTREE_H #define _WTREE_H #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #ifndef FALSE #define FALSE 0 #define TRUE 1 #endif // FALSE #define WORD_NUMBER 101 struct wtree { char c; char exp[201]; bool self; struct wtree *child[46]; }; extern int alpcompare(const char, const char); extern int word_tree_traveal_delete(struct wtree *); extern struct wtree *word_tree_search(char *, struct wtree *); extern int exchange(char str[]); extern int ptlen(struct wtree* pt[]); extern int alpcompare(const char a,const char b); extern struct wtree* word_tree_insert(char *str,char *exp,struct wtree *pt); extern bool word_tree_delete(char *str,struct wtree *pt); extern bool word_tree_child_enum(struct wtree* pt); extern int word_tree_traveal(struct wtree* pt,char *str,FILE *fp); extern int word_tree_traveal_delete(struct wtree* pt); extern int samewords; extern char TempFile[]; #endif
#include "func.h" #define COMANDOPT_LENTH 200 #define REPLACE_WORD_LENTH 100 #define fromFileEnterAndCheck(c) do{fread(&c,1,1,fp); }while ( ( c == ' ') && c != '\n' ) extern int getOption(char str[]); static struct wtree root; static char cmdInput[CMD_INPUT_LENTH]; static int outPutSleep; static char replaceWord[REPLACE_WORD_LENTH]; char cmdOption[COMANDOPT_LENTH]; int fun_search() { char words[WORD_NUMBER] = {0}; char wordExp[EXP_NUMBER] = {0}; /* 聲明單詞詞組和釋義詞組 */ int opt = 1; while ( 1 ) { // printf("%s %s %s\n",words,wordExp,replaceWord); lprint(); opt = getAndCheckWord( words,wordExp ); /*****0是返回命令 -1錯誤 1返回單詞 2替換單詞 -2未知錯誤*/ /* 顯示菜單*/ if ( opt == 0 ) /* 識別對應命令並調用對應函數 */ { return checkCmd(opt); } else if ( opt == 1 ) /*搜索查詢單詞*/ { char tempchar[WORD_NUMBER]; strcpy(tempchar,words); exchange(tempchar); struct wtree *res = word_tree_search(tempchar,&root); if (res != NULL && res->self == TRUE) { printf(" \t%s : ",words); printf("%s\n",res->exp); } else { printf(" \tNot Found!\n"); } } else if ( opt == 2 ) /*替換單詞*/ { strcpy(root.exp,wordExp); if (searchAndReplaceWord( words, replaceWord,&root) != -1) printf( " \tUpdate Sucessfully! \n" ); } else if ( opt == 3 ) { return 0; } else if ( opt == -1 || opt == -2 ) { ; } } } int searchAndReplaceWord(char w[],char r[],struct wtree *pt) { exchange(w); exchange(r); char temp1[WORD_NUMBER]; strcpy(temp1,w); struct wtree *temp = word_tree_search(temp1,&root); if (pt->exp[0] == '\0' && temp != NULL) { strcpy(pt->exp,temp->exp); } if (temp == NULL) { if (!word_tree_insert(r,&(pt->exp),pt)) return -1; } else { word_tree_delete(w,pt); word_tree_insert(r,pt->exp,pt); } pt->exp[0] = '\0'; return 0; } int fun_enter() { char words[WORD_NUMBER] = {0}; char wordExp[EXP_NUMBER] = {0}; /**** 聲明單詞詞組和釋義詞組 */ int opt = 1; while ( 1 ) { lprint(); //printf("%s %s %s\n",words,wordExp,replaceWord); opt = getAndCheckWord( words,wordExp ); /* 顯示菜單*/ if ( opt == 0 ) /*** 識別對應命令並調用對應函數 */ { return checkCmd(opt); } else if ( opt == 1 ) /***** 寫到樹里面 ***/ { exchange(words); word_tree_insert(words,wordExp,&root); printf(" \tSuccess!\n"); continue; } else if ( opt == 2 ) /***替換單詞*/ { strcpy(root.exp,wordExp); searchAndReplaceWord( words, replaceWord,&root); printf( "\tUpdate Sucessfully! \n" ); } else if ( opt == -1 || opt == -2 ) { printf( " \tInput error!\n" ); } } } int fun_ffile() { samewords = 0; int coun = 0; printf(" \tloading from file...please wait and do not exit...\n"); FILE *read; char word[WORD_NUMBER] = {0}; char wordExp[EXP_NUMBER] = {0}; int flag; read = fopen(cmdOption,"r"); if (read == NULL) { printf(" \topen file error!\n"); fun_tip = search; return 0; } else { while (1) { flag = get_from_file(read,word,wordExp); if (flag == -1) { printf("This word will be ignore\n"); continue; } else if (flag == 1) { char tempword[WORD_NUMBER]; strcpy(tempword,word); exchange(tempword); word_tree_insert(tempword,wordExp,&root); coun++; printf("%s\n",word); continue; } else if (flag == 0) { if( fclose(read) != 0) { perror("fclosed"); } printf("加載完畢!\n共輸入%d個單詞,其中%d為重復輸入。你想將數據排序輸出到文件嗎?[Y/n]:",coun,samewords); fflush(stdin); char c = getchar(); while (c == '\n' || c == 'Y' || c =='y') { cPrint("\n請輸入文件路徑:"); int flagfile = getOption_ffile(cmdOption); if (flagfile == -1 || isrightfile()) { if (strlen(cmdOption) == 0 && flagfile != -1) { printf(" \t沒有輸入任何路徑!\n"); } //else // { // printf(" \t錯誤的路徑!\n"); // } break; } fun_tip = ofile; fun_ofile(); return 0; } fflush(stdin); fun_tip = search; return 0; } } } } int getOption_ffile( char str[] ) { int c; int i = 0; EnterAndCheck(c); while ( 1 ) { if ( c == '\n' || c == EOF || c == ' ' ) { str[i] = '\0'; return(0); } else if ( isalpha( c ) || c == ':' || c == '\\' || c == '/' || c == '.' || c == '_' || isdigit( c ) ) { str[i++] = c; c = getchar(); continue; } else { str[0] = '\0'; cPrint( " \tIllegal file names\n" ); return(-1); } } return 0; } int get_from_file(FILE *fp, char *pWord,char *exp ) { char c; int i = 0; //int j = 0;//|warning: unused variable 'j' [-Wunused-variable]| pWord[0] = '\0'; exp[0] = '\0'; replaceWord[0] = '\0'; if (feof(fp)) //雖然現在這個語句看上去沒用,可能是有一個換行符,但是如果就真的一個字節都沒有呢 { return 0; } fromFileEnterAndCheck(c); /* */ if (feof(fp)) { return 0; } if ( c == '\n') { //printf( "Invalid input\n" ); return(-1); /**** 未檢測到有效內容 */ } while ( 1 ) { if (feof(fp)) { return 0; } if ( c == '\n' || c == EOF ) { /* 結束 */ pWord[i] = '\0'; while ( pWord[i - 1] == ' ' ) { pWord[i - 1] = '\0'; i--; } i = 0; if (c == EOF) { return 0; } return(1); } else if ( i == WORD_NUMBER ) { printf( " \tword too long\n" ); fread(&c,1,1,fp); while (c != '\n' && c != EOF); pWord[0] = '\0'; return(-1); } else if ( c == ' ' ) /**** 空格 */ { /* 單詞遇到多空格只保留一個 */ pWord[i++] = c; fread(&c,1,1,fp); while (c == ' ' ) /** ***空格后還是字母則認為是詞組,繼續 */ fread(&c,1,1,fp); continue; } else if ( isalpha( c ) || c == '.' ) { pWord[i++] = c; c = fgetc(fp); continue; } else if ( !isalpha( c ) && c != '.' ) /***不是字母也不是。輸入錯誤 */ { if (pWord[i-1] == ' ') { pWord[i-1] = '\0'; ungetc(c,fp); fgets(exp,200,fp); return 1; } else { // printf("%d",c); printf( " \t%c is a bad char!\n", c ); i = 0; pWord[0] = '\0'; while (c != '\n' && c != EOF && !feof(fp)) fread(&c,1,1,fp); return(-1); } } else { /*** * 是字母 也不是space \n eof * 正常情況,永遠不執行這一塊 */ printf( "error Input Word ,OH GOD ERROR" ); } } return(-2); } int fun_ofile(void) { FILE *fp = fopen(cmdOption,"a"); if (fp == NULL) { printf(" \t文件打開失敗!\n"); fun_tip = search; return 0; } word_tree_traveal(&root,NULL,fp); printf(" \t文件輸出完畢!\n"); fclose(fp); fun_tip = search; return 0; } void system_sleep(int sleepTime) { #ifdef _WIN32 Sleep(sleepTime); // Sleep(sleepTime); #else sleep(sleepTime); #endif //_WIN32 } int fun_outprint() { int i = 1; int flag; FILE* fp; int c; char w[WORD_NUMBER] = {0}; char e[EXP_NUMBER] = {0}; if (strlen(cmdOption) == 0) outPutSleep = DEF_PRINT_TIME; else if (strlen(cmdOption) == 1) { outPutSleep = atof(cmdOption) * 1000; } //printf("%d",outPutSleep); if (access(TempFile, F_OK) == 0) remove(TempFile); fp = fopen(TempFile,"w"); if (fp == NULL) { printf(" \t文件打開失敗!\n"); return 0; } else { word_tree_traveal(&root,NULL,fp); fseek(fp,0L,SEEK_SET); fclose(fp); } fp = fopen(TempFile,"r"); if (fp == NULL) { printf(" \t文件打開失敗!\n"); return 0; } while(1) { flag = get_from_file(fp,w,e); if (flag == -1) { printf("\r\r\r\r\r\r"); continue; } else if (flag == 1) { if (strlen(w) == 0 || w[0] == '\n') continue; printf("\n \tNO.%d: %s : ",i,w); printf("%s",e); i++; system_sleep(outPutSleep); if(kbhit()) /**** WARNING implicit declaration of function 'kbhit' ***/ { if (c = getch() == 'q') /**** warning: suggest parentheses around assignment used as truth value [-Wparentheses]| ***/ { printf(" \t用戶取消操作!\n"); fclose(fp); remove(TempFile); fun_tip = search; return 0; } } continue; } else if (flag == 0) { if( fclose(fp) != 0) { perror("fclosed"); } printf(" \t全部輸出完畢!\n"); //fclose(fp); remove(TempFile); fun_tip = search; return 0; } } } int fun_help() { cmdHelp(); return 0; } static void clean_stdin_buffer(void) { scanf("%*[^\n]"); scanf("%*c"); } bool isrightfile() { return (strlen(cmdOption) == 0 || cmdOption[strlen(cmdOption) - 1] == '\\' || cmdOption[strlen(cmdOption) - 1] == '/'); } bool isrighttime() { return (strlen(cmdOption) == 0 || strlen(cmdOption) > 2); } int checkCmd( int opt ) { int flag; /*** enter option *****/ if (!strcmp( "ofile", cmdInput ) || !strcmp( "ffile", cmdInput ) ) { flag = getOption(cmdOption); if (flag == -1 || isrightfile()) { fun_tip = search; if (strlen(cmdOption) == 0) { printf(" \t請輸入文件路徑!\n"); } else if (!isdigit(cmdOption)) { printf(" \t請檢查文件路徑是否正確!\n"); } return 0; } } else if ( !strcmp( "outprint", cmdInput )) { flag = getOption(cmdOption); if (flag == -1 || isrighttime()) { fun_tip = search; if (strlen(cmdOption) == 0) { printf(" \t請正確輸入時間\n"); } else if (!isdigit(cmdOption[0])) { printf(" \t請檢查時間是否正確!(1 -99)\n"); } return 0; } } else { fflush(stdin); } if ( !strcmp( "clean", cmdInput ) ) { word_tree_traveal_delete(&root); printf(" \t數據清理完畢!\n"); return(0); } else if ( !strcmp( "outprint", cmdInput ) ) { fun_tip = outprint; return(0); } else if ( !strcmp( "ofile", cmdInput ) ) { fun_tip = ofile; return(0); } else if ( !strcmp( "ffile", cmdInput ) ) { fun_tip = ffile; return(0); } else if ( !strcmp( "help", cmdInput ) ) { fun_tip = help; return(0); } else if ( !strcmp( "exit", cmdInput ) ) { word_tree_traveal_delete(&root); exit( 0 ); return(0); } else if ( !strcmp( "search", cmdInput ) ) { fun_tip = search; return(0); } else if ( !strcmp( "enter", cmdInput ) ) { fun_tip = enter; return(0); } else if ( !strcmp( "cls", cmdInput ) ) { cmdCls(); return(0); } else if ( !strcmp( "menu", cmdInput ) ) { cmdMenu(); return(0); } else if ( !strcmp( "update", cmdInput ) ) { /* cmdUpdate(); */ printf( "update words please use \" << \"\n" ); return(0); } else { printf( " \tcan not found the conmand: %s!\n", cmdInput); return(-1); } } int getOption( char str[] ) { int c; int i = 0; EnterAndCheck(c); if ( c != '-' && c != 'f' ) { str[0] = '\0'; ungetc(c,stdin); fgets(cmdOption,300,stdin); if (access(cmdOption,F_OK) == 0) { return 0; } else if(isdigit(c)) { if ( strlen(cmdOption) == 1) return 0; else if (isdigit(cmdOption[1])) return 0; else return -1; } cPrint( " \tWrong argument\n" ); return -1; } else if ( (c = getchar() ) == '=' ) { c = getchar(); while ( 1 ) { if ( c == '\n' || c == EOF || c == ' ' ) { str[i++] = '\0'; return(0); } else if ( isalpha( c ) || c == ':' || c == '\\' || c == '/' || c == '.' || c == '_' || isdigit( c ) ) { str[i++] = c; c = getchar(); continue; } else { str[0] = '\0'; cPrint( " \tIllegal file names\n" ); return(-1); } } } else if ( isdigit( c ) ) { str[i++] = c; c = getchar(); if ( isdigit( c ) ) { str[i++] = c; if ( isdigit( c = getchar() ) ) { str[0] = '\0'; cPrint( " \tTime must be within 1-99.\n" ); return(-1); } else { str[i] = '\0'; return(0); } } else if ( c == '\n' || c == ' ' ) { str[i] = '\0'; return(0); } else { str[0] = '\0'; fflush(stdin); printf( " \tWrong argument\n" ); return(-1); } } else { printf( "%c", c ); fflush(stdin); printf( " \tWrong argument\n" ); } return 0; } int cmdHelp() { system( "cls" ); printf( "\n" ); printf( "在主界面直接輸入單詞以查詢已有數據\n默認數據將保存到程序目錄minidict.mi文件\n" ); printf( "* 使用命令提示符 >> 進行操作\n" ); printf( " 例 >>help 將顯示本頁面\n" ); printf( "\n" ); printf( "* FFILE f=[file] 從file文件輸入數據\n" ); printf( "* ENTER 進入連續錄入模式,該模式下可手動連續輸入數據\n" ); printf( "* MENU 回到主界面\n" ); printf( "* CLS 清空屏幕\n" ); printf( "* [wors] << [word] 將wors 替換為 word\n" ); printf( "* OUTPRINT -[t] 將已有數據以t秒為間隔輸出到屏幕 留空為5秒\n" ); printf( "* OFILE f=[file] 將數據輸出到file\n" ); printf( "* HELP 顯示本頁\n" ); printf( "* EXIT 退出程序\n" ); printf( "\n" ); printf( "回車退出" ); int c; while ( c = getchar() != '\n' ) /**** warning: suggest parentheses around assignment used as truth value [-Wparentheses]| ***/ ; system( "cls" ); miniDict(); Menu(); return(0); } int cmdMenu() { system( "cls" ); miniDict(); Menu(); return(0); } int cmdCls() { system( "cls" ); miniDict(); Menu(); return(0); } int getAndCheckWord( char *pWord,char *exp ) { int c; int i = 0; //int j = 0; /***** unused j ****/ /****** 清空數組 */ pWord[0] = '\0'; exp[0] = '\0'; replaceWord[0] = '\0'; EnterAndCheck(c); /* */ if ( c == '\n' || c == EOF ) /* 第一個字符就無效 */ { printf( "\n" ); return(-8); /**** 未檢測到有效內容 */ } /**** 命令輸入 */ if ( c == '>' && (c = getchar() ) == '>' && i == 0 ) { EnterAndCheck(c); while ( 1 ) { if ( c == '\n' || c == ' ' ) { cmdInput[i] = '\0'; return(0); } else if ( i == CMD_INPUT_LENTH ) { clean_Print( "\ttoo long arg\n" ); cmdInput[0] = '\0'; i = 0; return(-1); } else if ( !isalpha( c ) ) { printf( " \t' %c 'bad conmand\n", c ); cmdInput[0] = '\0'; fflush(stdin); i = 0; return(-1); } cmdInput[i++] = tolower( c ); /* /將命令轉換為小寫 */ c = getchar(); continue; } } /*** * 命令輸入完畢 * 正常 單詞輸入開始 */ while ( 1 ) { if ( c == '\n' || c == EOF ) { /* 結束 */ pWord[i] = '\0'; while ( pWord[i - 1] == ' ' ) { pWord[i - 1] = '\0'; i--; } i = 0; return(1); } else if ( i == WORD_NUMBER ) { cPrint( " \tword too long\n" ); pWord[0] = '\0'; return(-1); } else if ( c == '<') { if ((c = getchar() ) != '<' ) { if (fun_tip == enter && pWord[i-1] == ' ') { pWord[i - 1] = '\0'; ungetc(c,stdin); ungetc('<',stdin); fgets(exp,200,stdin); return 1; } else { ungetc(c,stdin); fgets(exp,200,stdin); printf(" \terror: '%s<%s ' is not a word!\n",pWord,exp); fflush(stdin); pWord[0] = '\0'; exp[0] = '\0'; return -1; } } int errorTemp = getAndCheckWord( replaceWord,exp); if ( errorTemp == -1 ) { pWord[0] = '\0'; return -1; /**** 如果替換單詞錄入出錯,那么清空前面錄入的單詞 */ } pWord[i] = '\0'; while ( pWord[i - 1] == ' ' ) { pWord[i - 1] = '\0'; i--; } return(2); } else if ( c == ' ' ) /**** 空格 */ { /* 單詞遇到多空格只保留一個 */ pWord[i++] = c; while ( (c = getchar() ) == ' ' ) /** ***空格后還是字母則認為是詞組,繼續 */ ; continue; } else if ( isalpha( c ) || c == '.' ) { pWord[i++] = c; c = getchar(); continue; } else if (( !isalpha( c ) && c != '.')) /***不是字母也不是。輸入錯誤 */ { int lrn; if (pWord[i-1] == ' ' && fun_tip == enter) { pWord[i-1] = '\0'; ungetc(c,stdin); fgets(exp,200,stdin); return 1; } else { pWord[i++] = c; pWord[i] = '\0'; char tempfile2[300]; fgets(tempfile2,300,stdin); strcpy(cmdOption,pWord); strcat(cmdOption,tempfile2); lrn = strlen(cmdOption); cmdOption[lrn - 1] = '\0'; // printf("%s %s %s",pWord,tempfile2,cmdOption); if (access(cmdOption,F_OK) == 0 && cmdOption[lrn - 2] != '\\' &&cmdOption[lrn - 2] != '/') { int temp = fun_tip; fun_tip = ffile; fun_ffile(); fun_tip = temp; return 3; } } cmdOption[5] = '\0'; strcpy(pWord,cmdOption); strlwr(pWord); if (strcmp(pWord,"ffile") == 0 || strcmp(pWord,"ofile")) { int co; for (co = 6; co < lrn - 1; co++) { cmdOption[co - 6] = cmdOption[co]; } cmdOption[co - 6] = '\0'; lrn = strlen(cmdOption); } if (access(cmdOption,F_OK) == 0 && cmdOption[lrn - 2] != '\\' &&cmdOption[lrn - 2] != '/') { int temp = fun_tip; fun_tip = ffile; fun_ffile(); fun_tip = temp; return 3; } printf( " \terror:' %s ' is not a word!\n",cmdOption ); fflush(stdin); i = 0; cmdOption[0] = '\0'; pWord[0] = '\0'; exp[0] = '\0'; return(-1); } else { /*** * 是字母 也不是space \n eof * 正常情況,永遠不執行這一塊 */ printf( " \terror Input Word ,OH GOD ERROR" ); } } return(-2); /**** 測試臨時,正常永遠不會返回-2 */ }
/************************************************************************* > File Name: func.h > Author: > Mail: > Created Time: Thu 30 Jan 2020 08:01:53 AM HKT ************************************************************************/ #ifndef _FUNC_H #define _FUNC_H #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <windows.h> #include <conio.h> #include "common.h" #include "wtree.h" #define DEF_PRINT_TIME 1 #define CMD_INPUT_LENTH 30 #define EXP_NUMBER 201 #define EnterAndCheck(c) while ( ( (c = getchar() ) == ' ') && c != '\n' ) extern char cmdOption[]; extern int getOption_ffile(char []); extern bool isrightfile(); extern bool isrighttime(); extern int getAndCheckWord( char *pWord,char *exp ); extern int cmdCls(); extern int cmdMenu() ; extern int cmdHelp(); extern int checkCmd( int opt ); extern int fun_outprint(); extern void system_sleep(int sleepTime); extern int fun_ofile(void); extern int get_from_file(FILE *fp, char *pWord,char *exp ); extern int getOption_ffile( char str[] ); extern int fun_ffile(); extern int fun_enter(); extern int searchAndReplaceWord(char w[],char r[],struct wtree *pt); extern int fun_search(); #endif
/************************************************************************* > File Name: common.c > Author: > Mail: > Created Time: Thu 30 Jan 2020 06:57:03 AM HKT ************************************************************************/ #include "common.h" char beauty[600]; enum funtip fun_tip; void clean_Print(const char *str) { int ch; printf("%s", str); while ((ch = getchar() != '\n') && ch != EOF); } void cPrint(const char *str) { // char temp[1024]; // fgets(temp, sizeof(temp), stdin); fflush(stdin); printf("%s", str); } void lprint(void) { switch (fun_tip) { case search: printf( "Serach $ " ); break; case enter: printf( "Enter > " ); break; case ffile: printf( "File > " ); break; case help: printf( "Help > " ); break; case outprint: printf( "Output > " ); break; default: printf( "prefix變量異常改變!" ); } } void temprint(void) { strcpy(beauty, " \t .::::. \n* .::::::::. \n* ::::::::::: FUCK YOU \n* ..:::::::::::' \n* ':::::::::::' \n* .:::::::::: \n* '::::::::::::::.. \n* ..::::::::::::. \n* ``:::::::::::::::: \n* ::::``:::::::::' .:::. \n* ::::' ':::::' .::::::::. \n* .::::' :::: .:::::::'::::. \n* .:::' ::::: .:::::::::' ':::::. \n* .::' :::::.:::::::::' ':::::. \n* .::' ::::::::::::::' ``::::. \n* ...::: ::::::::::::' ``::.\n* ```` ':. ':::::::::' ::::..\n* \'.:::::\' \':'````.."); } void strprint(char str[],int t) { int i; printf("\n"); for (i = 0; i < strlen(str); i++) { if (str[i] == '\n') { printf("\n"); } else if (str[i] == '\0') { i = strlen(str); } else { printf("%c",str[i]); } } printf("\n"); system_sleep(t * 1000); } void miniDict(void) { printf( " \n ,, ,, ,,\n" ); printf( " 7MMM. ,MMF' db db `7MM\"\"\"Yb. db mm \n" ); printf( " MMMb dPMM MM `Yb. MM \n" ); printf( " M YM ,M MM `7MM `7MMpMMMb. `7MM MM `Mb `7MM ,p6\"bo mmMMmm \n" ); printf( " M Mb M' MM MM MM MM MM MM MM MM 6M' OO MM \n" ); printf( " M YM.P' MM MM MM MM MM MM ,MP MM 8M MM \n" ); printf( " zM `YM' MM MM MM MM MM MM ,dP' MM YM. , MM \n" ); printf( " .JML. `' .JMML.JMML.JMML JMML.JMML.JMMmmmdP' .JMML.YMbmd' `Mbmo\n" ); printf( "\n" ); } void Menu() { printf( "\n直接輸入單詞回車以查詢單詞。 \n" ); printf( "\t\t*1 直接輸入單詞以查詢 \n"); printf( "\t\t*2 >>ffile 從文件錄入 \n"); printf( "\t\t*3 >>enter 進入錄入模式 \n"); printf( "\t\t*4 >>help 顯示幫助信息 \n"); //printf( "\t\t*5 >>menu 退出當前操作回到主菜單 \n"); printf( "\t\t*5 >>exit 退出程序 \n"); printf( "\n" ); printf( "\n" ); }
/************************************************************************* > File Name: common.h > Author: > Mail: > Created Time: Thu 30 Jan 2020 06:57:21 AM HKT ************************************************************************/ #ifndef _COMMON_H #define _COMMON_H #include <stdio.h> #include <string.h> extern void clean_Print(const char *); extern void cPrint(const char *); extern void lprint(void); extern void temprint(void); extern void strprint(char [], int); extern void miniDict(void); extern void Menu(void); extern char beauty[]; /** 枚舉 命令標記 ***/ enum funtip { help = 0, search, enter, ffile, ofile, outprint }; extern enum funtip fun_tip; #endif