2017-03-15 3 views
1

私のプログラムでQSortを使用して、ポインタの要素をstructへのポインタにソートする必要があります。最初の要素は大丈夫ですが、それはうんざりです。この関数はいくつかの要素を読んでいるが、間違った順序/位置にあるようです。QSortがcmp関数内で間違った(スクランブルされた?)番号を返す

は、ここに入力した後に私のコード

... 

typedef struct Date { 
    int day; 
    int month; 
    int year; 
} Date; 

... 

// Sorts the date date_num - the number of entered dates, dates - pointer to pointers to structs of dates 
void sort_dates(int* date_num, Date** dates){ 

    // Normalize the year 
    int d; // The date 
    for(d=0;d<*date_num;d++){ 
     if(dates[d]->year >= 90 && dates[d]->year <= 99){ 
      dates[d]->year = (dates[d]->year)+1900; 
     } else{ 
      dates[d]->year = (dates[d]->year)+2000; 
     } 
    } 

    qsort(dates[0], *date_num, sizeof(Date), compare); 

} 

int compare(const void* a, const void* b){ 

    Date* date1 = (Date*)a; 
    Date* date2 = (Date*)b; 

    // Concatenate year, month and day 
    long num1 = date1->year; 
    long num2 = date2->year; 

    // Concatenate month 
    num1 = num1*100+(date1->month); 
    num2 = num2*100+(date2->month); 

    // Concatenate day 
    num1 = num1*100+(date1->day); 
    num2 = num2*100+(date2->day); 

    printf("num1 = %d %d %d, num2 = %d %d %d\n", date1->year, date1->month, date1->day, date2->year, date2->month, date2->day); 

    //return (num2 - num1); 
    return 0; // Sorting Temporarily disabled 

} 

です:

January 1 01 
January 1 00 
February 28 99 
July 17 12 
September 10 12 
July 1 00 
June 30 90 
August 25 06 
May 27 08 
October 1 03 

プログラムはDate** datesに数字や店舗の日付に月の名前を変換します。これを実行した後、私は形式でこのような何か num1 = year month day, num2=year month day期待:

num1 = 2001 1 1, num2 = 2012 9 10 
num1 = 2012 9 10, num2 = 2000 7 1 
... 

をしかし、それは実際にそのような何かを返します:私は、各ブロックのサイズに問題がある可能性がありと思われる

num1 = 2001 1 1, num2 = 0 0 0 
num1 = 0 2000 1, num2 = 33 0 0 
num1 = 1 0 33, num2 = 0 2000 1 
num1 = 2001 1 1, num2 = 1 0 33 
num1 = 0 0 0, num2 = 1 0 33 
num1 = 2 28 0, num2 = 0 0 1999 
num1 = 2012 7 17, num2 = 0 0 0 
num1 = 0 33 0, num2 = 2012 7 17 
num1 = 2 28 0, num2 = 0 33 0 
num1 = 0 0 1999, num2 = 0 33 0 
num1 = 2001 1 1, num2 = 2 28 0 
num1 = 0 0 0, num2 = 2 28 0 
num1 = 1 0 33, num2 = 2 28 0 
num1 = 0 2000 1, num2 = 2 28 0 
num1 = 33 0 0, num2 = 2 28 0 

を例としてソートされます。年はいくつかの要素に間違った位置(最初とは異なる)ですが、論理的には正しいと思われます。

+0

は 'sizeof(* Date)'でなければなりません。 –

+1

@PeterMiehle構文エラーです。 :)多分あなたは 'sizeof(Date *)'を意味していたでしょう。 – unwind

+0

upps申し訳ありませんが、あまりにも多くのgolang –

答えて

2

この:

qsort(dates[0], *date_num, sizeof(Date), compare); 

あなたがdatesをソートする場合は、その最初の要素、qsort()datesを渡していない、間違っています。また、並べ替えるサイズは、ポインタのサイズ(つまり、sizeof (Date *))、それ以上にはsizeof *datesです。

さらに、比較関数では、datesの要素へのポインタ、つまりDateへのポインタへのポインタが渡されることは考慮されていません。これは、起動する必要があります意味:qsort()に比較関数がソート取得された配列の要素への2つのポインタが渡されているので

static int compare(const void* a, const void* b){ 
    const Date * const date1 = *(const Date**) a; 
    const Date * const date2 = *(const Date**) b; 

繰り返しますが、この変更が必要とされています。それは合理的なことです、それは要素自体を渡すことはできません(彼らの型を知らない)が、const void *はどのような種類のデータを指すことができます。配列要素のタイプがDate *Dateへのポインタ)であるため、compare()に送信される実際の値はDate(つまりDate **)へのポインタへのポインタです。

最後に、constを削除する必要はありません。そのようにしないでください。

+0

最後の段落を明確にするには: 'Date * date1 =(Date *)a;'は 'Date * date1 = *(Date **)a;' – user694733

+0

でなければなりません。 !あなたは、これらの機能がどのように「比較」機能の仕組みにどのように変化するのか、私に説明できますか?それは私のためにとても混乱しています – Jojko

+0

@Jojko私はもう少し言葉を追加しようとしました。 – unwind

関連する問題