C言語ケーススタディ ディレクトリ(フォルダ)の内容を表示するDIRコマンドの作り方1




2014年10月より個人の方を対象に、Study C無料提供を開始しました。
C言語を勉強中の方は、学習・教育に最適なC言語インタープリタのStudy Cを使ってみてください(個人の方は無料です)。
大学・高専・高校などの教育機関での採用実績も多数あるロングセラー商品Study Cが、個人向けに無料提供を始めました。
インタープリタの手軽さに加え、ゲームや3Dタートルグラフィックで楽しく勉強したりと、C言語の学習を強力にサポートします。
ブロック崩しゲーム 3Dツリー クリスマスツリー
また、このようなボタンの用意されているページでは、掲載しているプログラムをStudy Cに直接ロードし実行したりすることができます。
Study Cにロードする Study Cにロードし編集する Study Cにロードし実行する
Study C無料利用についての詳細は、このページを参照してください。



ディレクトリ(フォルダ)内にどのようなファイルやディレクトリが含まれているか表示するプログラムを作成します。 ちょうどコマンド プロンプトのDIRコマンドの簡易版を作成します(Study CのコマンドモードでもDIRコマンドが使用できます)。

指定したディレクトリ内の内容を取得する関数は、使用するOSによって異なります。 たとえばLinux(UNIX)ではopendir()/readdir()/closedir()関数という3個の関数を使用します。 Windowsでは、FindFirstFile()/FindNextFile()/FindClose()関数という3個の関数を使用します。
(1)どのディレクトリを調べるかはFindFirstFile()関数の引数で指定します。
(2)ファイル/ディレクトリが見つかるとFindFirstFile()関数はその情報をWIN32_FIND_DATA構造体(2番目の引数で渡します)にセットします。
(3)ファイル/ディレクトリが見つかるとFindFirstFile()関数はHANDLEにINVALID_HANDLE_VALUE以外の値を返します。
(4)2番目以降のファイル/ディレクトリはFindNextFile()関数で取得します。
(5)ファイル/ディレクトリ名はWIN32_FIND_DATAのcFileNameメンバにセットされます。
(6)FindNextFile()関数はファイル/ディレクトリが見つからないとFALSEを返します。
(7)最後にFindClose()関数でHANDLEをクローズします。

#include <stdlib.h>

main()
{
        WIN32_FIND_DATA fd;
        HANDLE  h;

        if((h = FindFirstFile("c:\\*.*", &fd)) == INVALID_HANDLE_VALUE){
                return;
        }
        do{
                printf("%s\n", fd.cFileName);
        }while (FindNextFile(h, &fd));
        FindClose(h);
}

使い方を説明すると結構複雑ですが、プログラムにしてしまえば上記のような比較的簡単なプログラムになります。 do - whileを使用しているのはFindFirstFile()関数が返したfd.cFileNameの結果も表示するためループの形式が好都合です(もちろんforループなどでも記述できます)。

このプログラムでは、fdで返される情報がファイルなのかディレクトリなのか不明です。 このような情報はdwFileAttributesメンバにセットされる情報で判断します。 dwFileAttributesメンバにセットされる情報はdirent.hに定義されている値の組み合わせで構成されます。

この中から次の3個を説明します。
(1)FILE_ATTRIBUTE_DIRECTORY
データがディレクトリであることを意味します。
(2)FILE_ATTRIBUTE_SYSTEM
データがシステム属性であることを意味します。
(3)FILE_ATTRIBUTE_HIDDEN
データが隠し属性であることを意味します。

上記の値はdwFileAttributesとAND(&)を取って検査します。隠し属性でシステム属性といったように複数の属性と一致することもあります。

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

main()
{
        WIN32_FIND_DATA fd;
        HANDLE  h;

        if ((h = FindFirstFile("c:\\*.*", &fd)) == INVALID_HANDLE_VALUE){
                return;
        }
        do {
                if((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0){
                        printf("[D]");
                }
                if((fd.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) != 0){
                        printf("[S]");
                }
                if((fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0){
                        printf("[H]");
                }
                printf(" %s\n", fd.cFileName);
        }while (FindNextFile(h, &fd));
        FindClose(h);
}

このプログラムはディレクトリの場合は[D]、システム属性の場合は[S]、隠し属性の場合は[H]と表示されます。