2016-09-05 3 views
2

私は、コマンドの並べ替えの機能の一部を実装するためのMac OSを使用しています:私のコードの 一部は以下の通りです:私のqsortがLinuxで何が問題になっていますか?

int compare(const void *p, const void *q) { 
    return strcmp(*(char **)p, *(char **)q); 
} 
void sort_file(char *filename, int unique, int reverse) { 
    /* TODO: Complete this function */ 
    /* Note: you will probably need to implement some other functions */ 
    char buf[1024][1024]; 
    int i=0; 
    FILE * fp; 
    if(!(fp=fopen(filename,"r"))){ 
     perror("Open error!"); 
     exit(0); 
    } 
    while(fgets(buf[i],1024,fp)){ 
     printf("%s",buf[i]); 
     i++; 
    } 
    qsort(buf, i, sizeof(char *), compare); 
} 

結果を常にsegmentation fault: 11 誰もが問題だものを私に伝えることができて、それを修正する方法を示していますか?

私が知りたいことは、コードの最大サイズがファイル内で1行でわからない場合、どのように配列を定義するのですか?

私は、このページからアイデアを得る: http://www.anyexample.com/programming/c/qsort__sorting_array_of_strings__integers_and_structs.xml

+2

あなたのストライドは完全に間違っています。 'sizeof(char *)'は 'sizeof * buf'でなければなりません(btwは' char * 'より大きい大胆なロットです)。それについて考えてみて、コンパレータの変更方法を検討してください。最初に – WhozCraig

+0

をqsort(buf、i、1024、compare)と書いていますが、同じ問題 –

+0

誰もがなぜdownvoteですか? :< –

答えて

5

あなたはポインタの配列を持っていません。あなたは配列の配列を持っています。配列の配列内の各要素には、1024 charの特定の固定ストライドがあります。 qsortはそのことを知る必要があり、あなたはそれを伝えていません。これに

qsort(buf, i, sizeof(char *), compare); 

:まず、この変更qsort

qsort(buf, i, sizeof *buf, compare); 

すると、各 "事" はchar配列のあなたの配列であるどのように大きな知っています。

次に、コンパレータは、渡されるアドレスと配列の配列に関係するものを考慮して変更する必要があります。コンパレータに渡される各アドレスは、要素が配置される場所です。しかし、あなたの要素はそれぞれchar[1024]です。一部のchar[1024]のアドレスはchar**ではなく、char(*)[1024]です。ここにはポインタに関するポインタはありません。

int compare(const void *p, const void *q) 
{ 
    const char (*lhs)[1024] = p; 
    const char (*rhs)[1024] = q; 
    return strcmp(*lhs, *rhs); 
} 

次に、配列のオーバーフローを防ぐための制御ループにはリミッターはありません。要するに、この:1024は、マジックナンバーの散水を回避するために一定のどこかのように表現されるべきであると、

while(i < 1024 && fgets(buf[i],1024,fp)) 

、理想的には:

while(fgets(buf[i],1024,fp)) 

は、このする必要があります。

最後に、あなたの関数にはオープンFILE*がリークしています。良い計画ではありません。あなたのファイルポインタfclose()を確認してください。私が見

+0

しかしあなたの答えはまだそのエラーを引き起こす可能性があります... –

+0

@WeihengLi "そのエラー"より具体的になりたいですか?私はちょうど '/ usr/share/dict/words'から無作為に選ばれた1024個のエントリをソートしてあなたのコードで上記の変更をテストしました。 – WhozCraig

+0

申し訳ありませんが、あなたは正しいです。 –

2

問題:qsort

qsort(buf, i, sizeof(char *), compare); 

間違った引数をする必要がありますbuf+1buf間の差が1000 char秒であるので

qsort(buf, i, sizeof(buf[0]), compare); 

、それはsizeof(char*)を次のように使用すると間違っています3番目の引数。

引数の間違ったキャストcompare

に元のポインタは、型char (*)[1000]、ないchar**です。したがって、あなたが使用する必要があります:

int compare(const void *p, const void *q) { 

    char (*p1)[1000] = (char (*)[1000])(p); 
    char (*q1)[1000] = (char (*)[1000])(q); 

    return strcmp(*p1, *q1); 
} 
関連する問題