MW211 EXIT

devlog
C言語/readdir()とqsort()でscandir()を代用
2013年05月07日
「scandir()」は「opendir()、readdir()、closedir()、qsort()」を
まとめてやってくれる便利な関数だが、
「opendir()、readdir()、closedir()、qsort()」で同等のことをやるとしたら
以下のようになる。
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
【readdir()とqsort()を使用する例】
┌──────────────────────────────────────┐
│    typedef struct {                                                        │
│        char  name[256];                                                    │
│    } S_FILE;                                                               │
├──────────────────────────────────────┤
│    int            count   = 0;                                             │
│    DIR            *dir    = NULL;                                          │
│    struct dirent  *dirEnt = NULL;                                          │
│    S_FILE         dirFile[256];                                            │
├──────────────────────────────────────┤
│    dir = opendir(ディレクトリパス);    // オープン                         │
│    if (dir == NULL) {                                                      │
│        エラー処理;                                                         │
│    }                                                                       │
│    while (1) {                                                             │
│        dirEnt = readdir(dir);  // エントリ情報を取得                       │
│        if (dirEnt == NULL) {  // 取得終了                                  │
│            break;                                                          │
│        }                                                                   │
│        if (dirEnt->d_name[0] != '.') {  // 「.」「..」を除外する           │
│            continue;                                                       │
│        }                                                                   │
│        // ファイル名を取得                                                 │
│        snprintf(dirFile[count].name,                                       │
│                 sizeof(dirFile[count].name),                               │
│                 "%s",                                                      │
│                 dirEnt->d_name);                                           │
│        count++;                                                            │
│    }                                                                       │
│    closedir(dir);  // クローズ                                             │
├──────────────────────────────────────┤
│    // ソート                                                               │
│    qsort(&dirFile,                                // ソート対象            │
│          sizeof(dirFile) / (sizeof(dirFile[0])),  // 件数                  │
│          sizeof(dirFile[0]),                      // 一件あたりのサイズ    │
│          qsortComp);                              // qsort比較関数         │
└──────────────────────────────────────┘
「readdir()」の戻り値にて、「struct dirent」型のポインタに
エントリ情報(ファイル一覧)が取得される
戻り値が「NULL」(終了)となるまで順読みされる
#「readdir()」を使用するには前後に「opendir()」と「closedir()」が必要である
エントリ情報を配列等に採取し(その際、不要なものは読み飛ばししてしまう)、
最後に「qsort()」にて並び替えを行う
「qsort()」は構造体のソート(キーを基準に行ごとソートするような処理)も可能
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
【qsort比較関数の例】(ファイル名で昇順・降順にを並び替える)
┌──────────────────────────────────────┐
│int  qsortComp(const void*  s1,                                             │
│               const void*  s2)                                             │
│{                                                                           │
│    if (昇順の場合) {                                                       │
│        return strcmp((char *)(((S_FILE *)s1)->name),                       │
│                      (char *)(((S_FILE *)s2)->name));                      │
│    } else {                                                                │
│        return strcmp((char *)(((S_FILE *)s2)->name),                       │
│                      (char *)(((S_FILE *)s1)->name));                      │
│    }                                                                       │
│}                                                                           │
└──────────────────────────────────────┘
「qsort()」の第四引数にて、関数を指定することでソート条件を指定できる
関数は別途自分で定義しなければならない(関数名は任意)
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
分類:C/C++