转:http://www.cnblogs.com/buptLizer/archive/2012/04/12/2444565.html
这个问题来自一个面试题。
给两个文件,其中一个文件存在一万行左右的文本,将所有数据以行为元素进行排序,输出到文件2中。
拿到这个题,一看数据量大约一万行,内存应该没问题,感觉直接调用库函数qsort,写个cmp函数就
很容易搞定,没想到调试程序发现了一个小问题。
分析程序代码:
1 const int MAXLINE = 100; 2 const int MAXLEN = 256; 3 int mycmp(const void *p1, const void *p2) 4 { 5 char* s1 = (char *)p1; 6 char* s2 = (char *)p2; 7 cout<<s1<<" "<<s2<<endl; 8 return strcmp(s1, s2); 9 } 10 bool sort_file(char* file1, char* file2) 11 { 12 ifstream in(file1); 13 if(!in) 14 { 15 cerr<<"open file1 failed"<<endl; 16 return false; 17 } 18 char word[MAXLINE][MAXLEN]; 19 // char *word[MAXLINE]; 20 cout<<sizeof(word[0])<<endl; 21 int line_num = 0; 22 while(!in.eof()) 23 { 24 /* 25 char *tmp = new char[MAXLEN]; 26 in.getline(tmp, MAXLEN, '\n'); 27 word[line_num] = tmp; 28 */ 29 in.getline(word[line_num], MAXLEN, '\n'); 30 line_num++; 31 } 32 ofstream out(file2); 33 if(!out) 34 { 35 cerr<<"open file2 failed"<<endl; 36 return false; 37 } 38 qsort(word, line_num, sizeof(word[0]), mycmp); 39 int i = 0; 40 while(i < line_num) 41 { 42 cout<<word[i]<<endl; 43 out<<word[i++]<<'\n'; 44 } 45 in.close(); 46 out.close(); 47 return true; 48 }
在这个代码中word为一个二维数组,那么每一个word[i]表示的其实是一个一维数组,我们知道如果使用一个char*来指向它的话,
那么可以直接利用这个char*来代表这个数组,所以在cmp函数中使用的是char*,看下面的例子。
版本二:
1 int mycmp(const void *p1, const void *p2) 2 { 3 char** s1 = (char**)p1; 4 char** s2 = (char**)p2; 5 cout<<*s1<<" "<<*s2<<endl; 6 return strcmp(*s1, *s2); 7 } 8 bool sort_file(char* file1, char* file2) 9 { 10 ifstream in(file1); 11 if(!in) 12 { 13 cerr<<"open file1 failed"<<endl; 14 return false; 15 } 16 // char word[MAXLINE][MAXLEN]; 17 char *word[MAXLINE]; 18 cout<<sizeof(word[0])<<endl; 19 int line_num = 0; 20 while(!in.eof()) 21 { 22 23 char *tmp = new char[MAXLEN]; 24 in.getline(tmp, MAXLEN, '\n'); 25 word[line_num] = tmp; 26 // in.getline(word[line_num], MAXLEN, '\n'); 27 line_num++; 28 } 29 ofstream out(file2); 30 if(!out) 31 { 32 cerr<<"open file2 failed"<<endl; 33 return false; 34 } 35 qsort(word, line_num, sizeof(word[0]), mycmp); 36 int i = 0; 37 while(i < line_num) 38 { 39 cout<<word[i]<<endl; 40 out<<word[i++]<<'\n'; 41 } 42 in.close(); 43 out.close(); 44 return true; 45 }
此时的word表示的是一个指针数组,每个word[i]就是一个char*,那么我们利用qsort的时候传递的是指向这个char* 的指针,即
char**,所以在cmp中需要将void* --> char**,然后用*s来表示char*传递给strcmp。
上面的例子说明,qsort 的比较函数中传递的是数组元素的指针,明白这个就很好理解了。
重复一下qsort 的参数:
void qsort ( void * base, size_t num, size_t size, int ( * comparator ) ( const void *, const void * ) );
base:指向第一个元素的指针,即数组首地址
num:要排序的元素个数,及数组长度
size:数组元素的大小,一般写成sizeof(base[0])
comparator:自己写的比较函数了