C言語入門講座。関数、サンプル集を参考にして、 C言語をマスターしよう。初心者から上級者まで。

配列要素を並べ変える

2012.08.10

qsort関数は、配列要素を値の大きさにより、昇順(小から大)または、降順(大から小)に並べ変えます。

#include <stdlib.h>
void qsort(void *base, size_t nmemb, size_t size,
          int(*compar)(const void *, const void *));

*baseは並べ変える配列を指定します。
nmembは配列の要素数を指定します。
sizeは配列要素の大きさをバイト単位で指定します。
*comparはソートキーの大小関係をqsort関数に知らせる関数を指定します。

戻り値はありません。

第4引数に指定する関数はqsort関数から呼び出され、仮引数として比較対象の2つの要素が渡ってきます。要素中のソートキーの大小関係をチェックして戻り値として、次の値を返します。(降順の場合は、大小を逆にします。)

  1. 第1引数が第2引数に対して小さい場合は、0より小さい値を返します。
  2. 第1引数と第2引数が等しい場合は、0を返します。
  3. 第1引数が第2引数に対して大きい場合は、0より大きい値を返します。

次の例題プログラムは、ファイルの内容を構造体配列に読み込んで、名前をキーにして昇順にソートしています。

プログラム 例

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

/* メンバーの個人情報 */
struct member {
  int      number;         /* 番号 */
  char     name[20];       /* 名前 */
  double   height;         /* 身長 */
  double   weight;         /* 体重 */
  double   jump;           /* 最高到達点 */
};
/* qsort関数のソートキー比較関数 */
int SortComp(const void *, const void *);

int main()
{
  FILE             *fp;
  struct member    member_list[20];
  struct member    *list_ptr;
  int              list_max;
  int              list_cnt;

  if ((fp = fopen('beijing_2008.csv', 'r')) == NULL) {
    fprintf(stderr, 'ファイルのオープンに失敗しました\n');
    abort();
  }

  list_ptr = member_list;
  list_max = 0;
  /* メンバー情報入力 */
  while(fscanf(fp, '%d,%[A-Za-z],%lf,%lf,%lf',
      &list_ptr->number, list_ptr->name, &list_ptr->height,
      &list_ptr->weight, &list_ptr->jump) != EOF) {
    ++list_ptr;
    ++list_max;
  }
  fclose(fp);

  /* member_listを名前をキーにしてソート */
  qsort(member_list, list_max, sizeof(struct member), SortComp);

  list_ptr = member_list;
  printf('番号 名前                   身長   体重  最高到達点\n');
  /* ソート後のメンバー情報出力 */
  for (list_cnt = 0; list_cnt < list_max; ++list_cnt, ++list_ptr) {
      printf('%3d  %-20s %6.1f %6.1f %6.1f\n',
        list_ptr->number, list_ptr->name, list_ptr->height,
        list_ptr->weight, list_ptr->jump);
  }

  return 0;
}

/* qsort関数のソートキー比較関数 */
int SortComp(const void *p1, const void *p2)
{
  struct member *cmp1 = (struct member *)p1;
  struct member *cmp2 = (struct member *)p2;

  return strcmp(cmp1->name, cmp2->name);
}

例の実行結果

$ cat beijing_2008.csv
1,kurihara,186,69,305
2,tajimi,180,70,309
3,takesita,159,52,280
4,oomura,184,70,319
5,takahasi,170,65,290
6,sano,159,54,260
7,sugiyama,184,66,310
8,sakurai,167,63,290
9,kanou,174,65,298
11,araki,186,79,307
12,kimura,184,66,298
14,kawai,168,63,280
$
$ ./qsort.exe
番号 名前                   身長   体重  最高到達点
 11  araki                 186.0   79.0  307.0
  9  kanou                 174.0   65.0  298.0
 14  kawai                 168.0   63.0  280.0
 12  kimura                184.0   66.0  298.0
  1  kurihara              186.0   69.0  305.0
  4  oomura                184.0   70.0  319.0
  8  sakurai               167.0   63.0  290.0
  6  sano                  159.0   54.0  260.0
  7  sugiyama              184.0   66.0  310.0
  2  tajimi                180.0   70.0  309.0
  5  takahasi              170.0   65.0  290.0
  3  takesita              159.0   52.0  280.0
$

関連記事