C 言語で opendir 関数を使用する

胡金庫 2023年10月12日
  1. ディレクトリストリームを開くために opendir 関数を使用する
  2. ディレクトリエントリの反復処理に readdir 関数を使用する
C 言語で opendir 関数を使用する

この記事では、C 言語で opendir 関数を使用する方法をいくつか説明します。

ディレクトリストリームを開くために opendir 関数を使用する

関数 opendir は POSIX 仕様の一部であり、<dirent.h> ヘッダファイルで定義されています。この関数は単一の char ポインタを引数にとり、開くディレクトリ名を指定します。opendirDIR* 構造体を返すか、エラーが発生した場合は NULL を返します。ディレクトリストリームを表現するために DIR データ型が実装されているが、ユーザは DIR 型のオブジェクトを割り当ててはならません。以下の例では、最初のコマンドライン引数で指定したディレクトリ名を受け取り、その値を opendir 関数に渡しています。

#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
  DIR *dp;
  struct dirent *dirp;

  if (argc != 2) {
    fprintf(stderr, "Usage: ./program directory_name\n");
    exit(EXIT_FAILURE);
  }

  dp = opendir(argv[1]);

  while ((dirp = readdir(dp)) != NULL) printf("%s\n", dirp->d_name);

  closedir(dp);
  exit(EXIT_SUCCESS);
}

ディレクトリエントリの反復処理に readdir 関数を使用する

ディレクトリストリームがオープンされ、有効な DIR* を取得したら、readdir 関数を用いてその中の各エントリを読み込むことができます。readdir 関数を呼び出すたびに、次のディレクトリのエントリを表す dirent 構造体へのポインタが返されます。ディレクトリストリームの終端に達すると、readdirNULL を返します。このようにして、開いたディレクトリストリームの各エントリを表示する単純な while ループを実装しました。また、opendirclosedir の関数呼び出しの周辺のコードを修正し、エラーをチェックして対応するメッセージを出力してデバッグに役立てるようにした。ライブラリの関数が正常に返されたかどうかをチェックするのは、常に良いことであり、安全な方法です。

#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
  DIR *dp;
  struct dirent *dirp;

  if (argc != 2) {
    fprintf(stderr, "Usage: ./program directory_name\n");
    exit(EXIT_FAILURE);
  }

  errno = 0;
  if ((dp = opendir(argv[1])) == NULL) {
    switch (errno) {
      case EACCES:
        printf("Permission denied\n");
        break;
      case ENOENT:
        printf("Directory does not exist\n");
        break;
      case ENOTDIR:
        printf("'%s' is not a directory\n", argv[1]);
        break;
    }
    exit(EXIT_FAILURE);
  }

  while ((dirp = readdir(dp)) != NULL) printf("%s\n", dirp->d_name);

  if (closedir(dp) == -1) perror("closedir");

  exit(EXIT_SUCCESS);
}

代わりに、readdir 関数にエラーチェックの条件文を追加することもできます。以下のコードは、繰り返しが成功した後にディレクトリの終端に到達した状態を追加で出力します。

#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
  DIR *dp;
  struct dirent *dirp;

  if (argc != 2) {
    fprintf(stderr, "Usage: ./program directory_name\n");
    exit(EXIT_FAILURE);
  }

  errno = 0;
  if ((dp = opendir(argv[1])) == NULL) {
    switch (errno) {
      case EACCES:
        printf("Permission denied\n");
        break;
      case ENOENT:
        printf("Directory does not exist\n");
        break;
      case ENOTDIR:
        printf("'%s' is not a directory\n", argv[1]);
        break;
    }
    exit(EXIT_FAILURE);
  }

  errno = 0;
  while ((dirp = readdir(dp)) != NULL) printf("%s\n", dirp->d_name);

  if (errno != 0) {
    if (errno == EBADF)
      printf("Invalid directory stream descriptor\n");
    else
      perror("readdir");
  } else {
    printf("End-of-directory reached\n");
  }

  if (closedir(dp) == -1) perror("closedir");

  exit(EXIT_SUCCESS);
}
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C File