标签:style http os io 使用 ar for 文件 art
#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct{char * key; //单词的指针int ntrans; //解释的个数char ** trans; //解释的指针数组}WORD, * pW;//词典使用帮助信息void show_help(){printf("./main -opt <-r/-w>\n");printf("-text load dict.txt and use\n");printf("-bin <-r/-w>load dict.dat and use\n");printf(" -r read dict.dat and use\n");printf(" -w read dict.txt and creat dict.dat\n");}//打印出错信息void sys_err(char * str){printf("%s \n",str);exit(-1);}//获取单词的个数int get_word_count(char * pathname){int len = 0;char buf[1024];FILE * fp = fopen(pathname , "r");if(!fp)sys_err("open file error!");while( fgets( buf , sizeof(buf) , fp) != NULL){len++;}return len / 2;}//为每个单词的解释开辟存储空间int trans_assign(pW w , char * str){int n = 0 , i = 0;char *tmp[50]; //临时指针数组,用来存储每个解释的指针【思想好】w->ntrans = 0;char *p = strtok( str , "@");if(!p) return 0;tmp[n++] = p;while( (p = strtok(NULL , "@")) != NULL)tmp[n++] = p;w->ntrans = n;w->trans = malloc( n * sizeof(char *));for( i = 0 ; i < n ; ++i){w->trans[i] = malloc( strlen(tmp[i]) +1 );strcpy(w->trans[i] , tmp[i]);}return n;}//把文本txt的内容初始化到结构体数组里void init_word_text(char * pathname , pW w , int n){int i , len;char buf[1024];FILE * fp = fopen( pathname , "r");if(!fp)sys_err("open file error!");for( i = 0 ; i < n ; ++i){// wordfgets( buf , sizeof(buf) , fp);len = strlen(buf);buf[ len - 1] = ‘\0‘; //把 \n 换成 \0w[i].key = malloc( len - 1);strcpy( w[i].key , buf + 1);// transfgets( buf , sizeof(buf) , fp);len = strlen(buf);buf[ len - 1] = ‘\0‘;trans_assign( &w[i] , buf + 6 );//+6表示把解释的Trans:去掉}fclose(fp);}//展示每一个单词和解释void show_word(WORD w){int i;// printf("%s\n" , w.key);// printf("%d\n" , w.ntrans);printf("\n");for( i = 0 ; i < w.ntrans ; ++i)printf("%-3d:%s\n",i+1,w.trans[i]);}//展示所有的单词及解释void show_word_arr(pW w , int n){int i;for( i = 0 ; i < n ; ++i)show_word(w[i]);}//交换两个结构体void swap(pW m , pW n){WORD temp = *m;*m = *n;*n = temp;}//用来查找快速排序的分割元素int partition(pW w , int l , int r){int i,j;for(i = l+1 , j = l ; i <= r ; ++i){if(strcmp(w[i].key , w[l].key) < 0){swap( &w[i] , &w[++j]);}}swap( &w[l] , &w[j]);return j;}//快速排序void quick_sort(pW w , int l , int r){if( l >= r) return;int k = partition(w , l , r);quick_sort(w , l , k-1);quick_sort(w , k+1 , r);}//排序接口函数void sort_word(pW w , int n){quick_sort( w , 0 , n-1);printf("初始化完成\n");}//判断用户是否退出int is_exit(char * str){if(strcmp(str,"exit") == 0)return 1;elsereturn 0;}//查找用户输入的单词,二分查找法int search_word(pW w , int n , char * str){int l = 0, r = n -1, mid;while( l <= r){mid = (l+r)/2;if(strcmp(w[mid].key , str) < 0)l = mid +1;else if(strcmp(w[mid].key , str) > 0)r = mid -1;elsereturn mid;}return -1;}//释放每个单词申请的动态内存void free_word(pW w , int n){int i,j;for(i = 0 ; i < n ; ++i){free(w[i].key);for(j = 0 ; j < n ; ++j){free(w[i].trans[j]);}free(w[i].trans);}}//把结构体数组写到二进制文件里void write_word_bin(char * pathname , pW word , int n){int i , j , len;FILE * fp = fopen( pathname , "w");//打开dict.bin准备写入fwrite( &n , sizeof(n) , 1 , fp);//先把总行数写进去for( i = 0 ; i < n ; ++i){len = strlen(word[i].key) + 1;// +1 这个坑啊fwrite( &len ,sizeof( int ), 1,fp ); // 写进去单词的长度fwrite( word[i].key , len , 1 , fp); //写进去单词的内容fwrite( &word[i].ntrans , sizeof( int ) , 1 , fp);//写进去解释的个数for( j = 0 ; j < word[i].ntrans ; ++j){len = strlen( word[i].trans[j] ) + 1;//计算出每个解释的长度fwrite( &len ,sizeof( int ), 1, fp );//写进去每个解释的长度fwrite( word[i].trans[j] , len , 1 ,fp );//写进去每个解释的内容}}fclose(fp);}//从二进制文件读到结构体数组内void read_from_bin(char * pathname , pW word , int n){int i , j , len;FILE * fp = fopen( pathname , "r");//打开dict.binfseek( fp , 4 , SEEK_SET);//偏移4个字节,因为之前取出4个总行数了for( i = 0 ; i < n ; ++i){fread(&len ,sizeof( int ), 1, fp );//把单词的长度读取出来word[i].key = malloc( len ); //为单词开辟存储空间fread( word[i].key , len , 1 , fp); //把单词读取出来fread( &word[i].ntrans , sizeof( int ) , 1 , fp);//把解释个数读取过来word[i].trans = malloc( word[i].ntrans * sizeof(char * ));//开辟解释空间for( j = 0 ; j < word[i].ntrans ; ++j){fread( &len ,sizeof( int ), 1, fp );//读取每个解释的长度word[i].trans[j] = malloc( len );//开辟每个解释的空间fread( word[i].trans[j] , len , 1 ,fp );//把每个解释读取出来}}fclose(fp);}int main(int argc , char * argv[]){if(argc < 2) //如果命令行参数小于2,退出{show_help();return -1;}int n , res , m;char buf[1024];pW word = NULL;if( strcmp(argv[1] , "-text") == 0) //但参数为-text时候,从文本读{n = get_word_count("dict.txt");word = malloc( n * sizeof(*word) );init_word_text("dict.txt", word , n);sort_word( word , n);// show_word_arr( word , n);}else if( strcmp(argv[1] , "-bin") == 0){if(argv[2]){if( strcmp(argv[2] , "-r") == 0){FILE * fp = fopen( "dict.bin" , "r");//打开dict.binif(!fp) sys_err("not bin file! now please\t-bin -w");fread( &n , sizeof( int ) , 1 , fp); //读取有多少行fclose( fp );word = malloc( n * sizeof(*word));//开辟结构体数组内存空间read_from_bin("dict.bin" , word , n);}else if( strcmp(argv[2] , "-w") == 0){n = get_word_count("dict.txt");word = malloc( n * sizeof(*word));init_word_text("dict.txt",word,n);sort_word( word , n);write_word_bin("dict.bin" , word , n);}else{show_help();return -1;}}else{show_help();return -1;}}else{show_help();return -1;}while(1){printf("please input your word : \n");fgets(buf,sizeof(buf),stdin);m = strlen(buf);buf[m-1] = ‘\0‘;if(is_exit(buf))break;res = search_word( word , n , buf);if(res != -1)show_word(word[res]);elseprintf("\nnot find\n");}free_word(word , n);free(word);return 0;}
标签:style http os io 使用 ar for 文件 art
原文地址:http://www.cnblogs.com/l6241425/p/3954945.html