1

私のプログラムは、コマンド ラインで指定されたディレクトリの内容を読み取ります。ディレクトリを再帰的に読み取ります。つまり、ディレクトリ「test」の内容を読み取り、その中に別のディレクトリ「inside」がある場合、「inside」という名前のディレクトリの内容も読み取ります。問題は、隠しディレクトリ、つまり「。」で始まるディレクトリを読み取らなくても正常に機能することです。. しかし、隠しディレクトリも読んだ場合、セグメンテーション違反と表示されます。

コードは次のとおりです。

メインファイル:

#include "helper.h"

/*
 * Display's content of String array passed to it,
 * that should conatin full path to files.
 */
void display(char **);

/*
 * Free's the memory utilized by the program
 */
void cleanup(char **);

int main(int argc, char *argv[])
{
    // ensure proper usage
    if (argc != 2)
    {
        printf("Usage: %s [dir]\n\n", argv[0]);
        return 1;
    }

    char **files = calloc(1, sizeof(char *));

    // get files from the directory specified
    getFiles(&files, argv[1]);

    // display files
    display(files);

    // free memory utilized by files array
    cleanup(files);

// that's all folks
return 0;
}


/*
 * Display's content of String array passed to it,
 * that should conatin full path to files.
 */
void display(char **files)
{
    // Color Red
//  printf("[0;31;40m");

    // display files
    for (int i = 0; files[i]; i++)
    {
        printf("%s\n", files[i]);
    }

    // turn off color
//  printf("[0;37;40m");
}


/*
 * Free's the memory utilized by the program
 */
void cleanup(char **files)
{
    // free memory utilized by files array
    for (int i = 0; files[i]; i++)
        free(files[i]);
    free(files);
}

getFiles 関数は、次のコードを含む helpers.c ファイルで定義されています。

#include "helper.h"
#include <dirent.h>
#include <stdlib.h>
#include <sys/types.h>

/*
 * Stores the list of files present in direectory pointed by 'dir' 
 * in array of strings pointed by 'files'
 */
void getFiles(char ***files, const char* dir)
{
    static int i;

    // ensure directory is valid
    if (dir == NULL)
    {
        printf("Error: Invalid Directory\n\n");
        exit(1);
    }

    // declare and initialize directory handler
    DIR *dd = opendir(dir);
    if (dd == NULL)
    {
        printf("Error: Directory Not Found\n\n");
        exit(2);
    }

    // structure that store file attributes read
    struct dirent *content;

    // read directory until all files are scanned
    while ((content = readdir(dd)) != NULL)
    {
        // ignore '.' and '..' directories
        if (strcmp(content->d_name, ".") == 0 || 
            strcmp(content->d_name, "..") == 0)
            continue;
        /*if (content->d_name[0] == '.')
            continue;*/

        //store full file path from current directory
        char temp[1024] = {0};

        // make full path
        makepath(temp, dir, content->d_name);

        // recall itself if another directory found
        if (isdir(temp))
        {
            // read this new directory found
            getFiles(files, temp);
            continue;
        }

        // allocate memory to store locations of char *
        *files = realloc(*files, (i + 2)*(sizeof(char *)));

        // allocate heap memory and store location
        *(*(files + 0) + i) = (char *)strdup(temp);

        // move to next location
        i++;
    }

    // free directory handler
    closedir(dd);

    // set NULL after last file name
    *(*(files + 0) + i) = '\0';
}


/*
 * returns true if 'dir' refers to a directory, false otherwise
 */
bool isdir(const char * dir)
{
    DIR *temp;
    temp = opendir(dir);

    if (temp != NULL)
    {
        closedir(temp);
        return true;
    }

return false;
}


/*
 * appends dir and file/directory name to src, 
 * thus makes a full file/directory path, from current directory
 */
void makepath(char src[], const char *dir, const char *file)
{   
    // prepend directory name
    strcat(src, dir);
    strcat(src, "/");

    // append file/directory name
    strcat(src, file);
}

必要なヘッダー ファイルは、helper.h ファイルに含まれています。

また、メモリ割り当てを間違えているのか知りたいと思っていました。(getFiles 関数の realloc で)。

隠しファイルを無視する行は、現時点で私がコメントしています。

/*if (content->d_name[0] == '.')
                continue;*/

上記の行のコメントを外すと、プログラムは正常に動作します。

readdir関数で読み取ったファイル名を保存している理由を考えている場合は、これらの名前が後で必要になるため、すぐにファイル名を表示しないのです。

このプログラムをより適切に実装する方法と、隠しディレクトリを読み取ったときに発生する問題を修正する方法についての提案。

4

1 に答える 1

1

それが問題かどうかはわかりませんが、ここにあります:

// set NULL after last file name
*(*(files + 0) + i) == '\0';

                     ^ you are not setting to NULL, you are comparing
于 2013-10-12T17:42:37.097 に答える