這個問題來自一個面試題。
給兩個文件,其中一個文件存在一萬行左右的文本,將所有數據以行為元素進行排序,輸出到文件2中。
拿到這個題,一看數據量大約一萬行,內存應該沒問題,感覺直接調用庫函數qsort,寫個cmp函數就
很容易搞定,沒想到調試程序發現了一個小問題。
分析程序代碼:
const int MAXLINE = 100;
const int MAXLEN = 256;
int mycmp(const void *p1, const void *p2)
{
char* s1 = (char *)p1;
char* s2 = (char *)p2;
cout<<s1<<" "<<s2<<endl;
return strcmp(s1, s2);
}
bool sort_file(char* file1, char* file2)
{
ifstream in(file1);
if(!in)
{
cerr<<"open file1 failed"<<endl;
return false;
}
char word[MAXLINE][MAXLEN];
// char *word[MAXLINE];
cout<<sizeof(word[0])<<endl;
int line_num = 0;
while(!in.eof())
{
/*
char *tmp = new char[MAXLEN];
in.getline(tmp, MAXLEN, '\n');
word[line_num] = tmp;
*/
in.getline(word[line_num], MAXLEN, '\n');
line_num++;
}
ofstream out(file2);
if(!out)
{
cerr<<"open file2 failed"<<endl;
return false;
}
qsort(word, line_num, sizeof(word[0]), mycmp);
int i = 0;
while(i < line_num)
{
cout<<word[i]<<endl;
out<<word[i++]<<'\n';
}
in.close();
out.close();
return true;
}
在這個代碼中word為一個二維數組,那么每一個word[i]表示的其實是一個一維數組,我們知道如果使用一個char*來指向它的話,
那么可以直接利用這個char*來代表這個數組,所以在cmp函數中使用的是char*,看下面的例子。
版本二:
int mycmp(const void *p1, const void *p2)
{
char** s1 = (char**)p1;
char** s2 = (char**)p2;
cout<<*s1<<" "<<*s2<<endl;
return strcmp(*s1, *s2);
}
bool sort_file(char* file1, char* file2)
{
ifstream in(file1);
if(!in)
{
cerr<<"open file1 failed"<<endl;
return false;
}
// char word[MAXLINE][MAXLEN];
char *word[MAXLINE];
cout<<sizeof(word[0])<<endl;
int line_num = 0;
while(!in.eof())
{
char *tmp = new char[MAXLEN];
in.getline(tmp, MAXLEN, '\n');
word[line_num] = tmp;
// in.getline(word[line_num], MAXLEN, '\n');
line_num++;
}
ofstream out(file2);
if(!out)
{
cerr<<"open file2 failed"<<endl;
return false;
}
qsort(word, line_num, sizeof(word[0]), mycmp);
int i = 0;
while(i < line_num)
{
cout<<word[i]<<endl;
out<<word[i++]<<'\n';
}
in.close();
out.close();
return true;
}
此時的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:自己寫的比較函數了