C 言語で opendir 関数を使用する
この記事では、C 言語で opendir
関数を使用する方法をいくつか説明します。
ディレクトリストリームを開くために opendir
関数を使用する
関数 opendir
は POSIX 仕様の一部であり、<dirent.h>
ヘッダファイルで定義されています。この関数は単一の char
ポインタを引数にとり、開くディレクトリ名を指定します。opendir
は DIR*
構造体を返すか、エラーが発生した場合は 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
構造体へのポインタが返されます。ディレクトリストリームの終端に達すると、readdir
は NULL
を返します。このようにして、開いたディレクトリストリームの各エントリを表示する単純な while
ループを実装しました。また、opendir
と closedir
の関数呼び出しの周辺のコードを修正し、エラーをチェックして対応するメッセージを出力してデバッグに役立てるようにした。ライブラリの関数が正常に返されたかどうかをチェックするのは、常に良いことであり、安全な方法です。
#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);
}