ページ 11

構造体のデータをソートしたいです。

Posted: 2013年6月27日(木) 15:41
by PSYCO
お世話になっております。C言語について質問です。こちらのプログラムでindexの項目に構造体をソートしたいのですがソートできません。間違いなどございましたらご指摘いただけるとありがたいです。

コード:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>


typedef struct
{
char country_code[4];
char name[64];
char num[4];
int index;
char date[8];
}STUDENT;

int CMP (const void *p, const void *q)
{
return ((STUDENT *) p)->num, ((STUDENT *) q)->num;
}


int main (void)
{
STUDENT student[] = {
{"111","rarara","12",90,"08/08"},
{"121","nanana","10",80,"09/20"},
{"122","hahaha","15",70,"01/10"},
{"120","bababa","50",100,"12/26"}
};
int i;
qsort (student, sizeof (student)/sizeof (student[0]), sizeof (student[0]), CMP);
for(i=0;i< sizeof (student)/sizeof (student[0]);i++)
printf("%s %s\n",student[i].country_code,student[i].num);
return 0;
} 

Re: 構造体のデータをソートしたいです。

Posted: 2013年6月27日(木) 15:58
by Blue
PSYCO さんが書きました:

コード:

int CMP (const void *p, const void *q)
{
return ((STUDENT *) p)->num, ((STUDENT *) q)->num;
}
ここ比較した結果を返してないですよね?

比較関数は
LEFT < RIGHT の場合は負の整数を
LEFT = RIGHT の場合は0を
LEFT > RIGHT の場合は正の整数を返すようにします。

STUDENTのnumは文字配列なので、その中に入っている数字列を数値として比較するなら、
atoiとかstrtolとかの関数を使って数値に変換後比較する。
(ex:1と2なら1のほうが小さい、2と10なら2のほうが小さい)

以下適当・・・

コード:

int left = atoi(((const STUDENT*)p)->num) ;
int right = atoi(((const STUDENT*)q)->num) ;
if (left < right) {
     return -1;
}
else if (left == right) {
    return 0;
}
else {
    return 1;
}
となるが、このルールなら単純に引き算した結果を返せばいい。

コード:

return atoi(((const STUDENT*)p)->num)  - atoi(((const STUDENT*)q)->num) ;
数字列としての比較ならstrcmp関数あたりでしょうか?
(ex:1と2なら1のほうが小さい、2と10なら10のほうが小さい)

Re: 構造体のデータをソートしたいです。

Posted: 2013年6月27日(木) 16:04
by PSYCO
すみません。間違えました。
numではなくてindexでソートしたいです。
大変申し訳御座いません。

Re: 構造体のデータをソートしたいです。

Posted: 2013年6月27日(木) 16:06
by Blue
indexのほうがキーなの?
こっちはint型なんでそのまま引き算した結果をかえせばいいすね。

コード:

return ((const STUDENT*)p)->index - ((const STUDENT*)q)->index ;

Re: 構造体のデータをソートしたいです。

Posted: 2013年6月28日(金) 11:43
by PSYCO
ありがとうございます!
感謝いたします。