2016-04-07 10 views
3

試験の練習シートでは、河川データを使用して構造体を作成する必要があります。構造体は:qsort()とCの構造体の使用

struct river 
{ 
    char name[40]; //name of river max 40 char long 
    int length; 
    int drainage_area; 
} 

データは、data.txtというファイルを使用して、最大から最小の河川の長さまで編成されていると考えられます。このファイルには、次の情報を持っています

ナイル6650 334900

アマゾン6400 6915000

長江6300 1800000

ミシシッピ、ミズーリ6275298万

エニセイ川-アンガラ・Selenga 5539258万

イエロー5464 745000

OB-イルティシュ5410299万

コンゴ-Chambeshi 4700368万

は、だから私は、関数のqsort()を使用するために知っている、あなたは、比較関数が必要です。しかし、私はファイルが関わっているときにこれをどうやって行うのかについてはあまりよく分かりません。私は比較関数(一般的な比較関数)のための次を持っています:

int compare_rivers(void *r1, void *r2) 
{ 
    int *_r1 = (int *)r1; 
    int *_r2 = (int *)r2; 

    if(*_r1 > *_r2) 
    { 
     return -1; 
    } 
    if (*_r1 == *_r2) 
    { 
     return 0; 
    } 

    return 1; 
} 

私の質問はどうですか?私はファイルを開く方法と読む方法を知っていますが、これは配列を使う方法とは異なりますか?

説明は本当に役に立ちます。私は本格的なコードを求めていません。私はちょうど私がこれをやる方法の説明/例がほしいです!前もって感謝します!

答えて

4

ファイルを最初にメモリに読み込む必要があります。構造体の(ソートされていない)配列として格納します。

「大きいデータ」が含まれているため、この配列(?)を並べ替えることはおそらくありません。この場合、実際はそうではありませんが、私が知っていることは、これを認識することが課題の目的であるかもしれないことです。 qsortは、構造体全体をソートすると、多くのデータシャッフルを行います。

この配列と並行して、それぞれ未整列配列の構造体項目を指す構造体ポインタの配列を作成できます。

qsortをこのポインタの配列に適用します。比較関数は、フォーム

int (*compar)(const void* obj1, const void* obj2) 

を持っているしかし、あなたはポインタの配列をソートしているので、qsortが実際にポインタにあなたアドレスを渡すことに注意してください。その後、いくつかの意味のある形で内容を比較

const struct river* r1 = *(const struct river**)obj1; 

:だからあなたのような何かを行う必要があるでしょう。

2

ファイルをstruct riverの配列としてメモリに保持すると、compare関数は2つのstruct river pointerをパラメータとして取得します。だからまずそれらをキャストし、比較ロジックを行います。

struct river rivers[10]; // filled with the file 

qsort(rivers, 10, sizeof *rivers, compare_rivers); 

    int compare_rivers(const void *r1, const void *r2) 
    { 
     const struct river*_r1 = (const struct river *)r1; 
     const struct river*_r2 = (const struct river*)r2; 

     // do compare logic 
    }