0

コマンド ライン インタープリターからすべてのファイルとサブディレクトリを削除しようとしています。rmdir -s newFolder への呼び出しが行われると、すべてのファイルとサブフォルダーを調べてすべてのファイルを削除する関数 removeAll を呼び出します。

たとえば、ファイル newFolder を削除する場合は、すべてのファイルを削除して newFolder1 に移動します。newFolder1 のすべてのファイルを削除し、newFolder2 に移動してすべてのファイルを削除します。だから今、私は newFolder 2 にいて、newFolder、newFolder1、および newFolder2 は空です。

私の質問は、これら 3 つの空のフォルダーを再帰的にバックアップして削除する方法です。これを数時間デバッグして作業しましたが、取得できません。ありがとうございました

これは、1 つの空のフォルダーを正常に削除する関数です。それ以外の場合は、removeAll を呼び出します。

void MyShell::rmdir () {
//Error Check
if(argc != 3) {
    printf("USAGE: rmdir [-s] <directory>\n");      
    return;
}
else if(stricmp(cwd, argv[2]) == 0){
    printf("Cannot remove the current working directory");
    return;
}
if(_rmdir(argv[2]) == 0)
    return;

removeAll(argv[2]); 

}

関数 removeAll は、すべてのサブフォルダー内のすべてのファイルを正常に削除します

void removeAll(char *path)
{
    _chdir(path);

    _finddata_t data;

    intptr_t handle = _findfirst("*", &data);

    if(handle == -1)
    {
        return;
    }

    do 
    {
        if (strcmp(data.name, ".") == 0 || strcmp(data.name, "..") == 0)
        {
            continue;
        }

        remove(data.name);

        if(data.attrib & _A_SUBDIR)
        {
            removeAll(data.name);
        }

    } while(_findnext(handle, &data) != -1);

    _findclose(handle); 
}

すべてのサブフォルダーを再帰して削除するという私の考えは、findnext ループから抜けた後にメソッドを呼び出すことでした。

void removeDirectory(char *path)
{
    _finddata_t data;

    intptr_t handle = _findfirst("*", &data);

    if(handle == -1)
    {
        return;
    }

    do 
    {
        if (strcmp(data.name, ".") == 0 || strcmp(data.name, "..") == 0)
        {
            continue;
        }


        if(data.attrib & _A_SUBDIR)
        {
            if(_rmdir(data.name) == 0)
            {
                _chdir("..");
                removeDirectory(path);
            }

        }

    } while(_findnext(handle, &data) != -1);

    _findclose(handle); 
}
4

2 に答える 2

1

再帰の要点は、「戻る」必要がないことです。再帰ルーチンの各反復は、それ自体のレベルのみを処理してから、それ自体を再度呼び出すか、中断する必要があります。ほぼ完了したようです。RemoveAll ルーチンに対して次のようなことを試してください。

void removeAll(char *path)
{
    _chdir(path);

    _finddata_t data;

    intptr_t handle = _findfirst("*", &data);

    if(handle == -1)
    {
        return;
    }

    while(_findnext(handle, &data) != -1)   // changed from do..while to just while
    {
        if (strcmp(data.name, ".") == 0 || strcmp(data.name, "..") == 0)
        {
            continue;
        }

        if(data.attrib & _A_SUBDIR)
        {
            removeAll(data.name);
            _rmdir(data.name);    // <- moved this to here
        }
        else
        {
            remove(data.name);
        }
    }

    _findclose(handle); 
}
于 2013-06-11T21:04:55.190 に答える
1

remove() が空のディレクトリとファイルを削除すると仮定すると、コードを次のように再配置する必要があります。

do 
{
    if (strcmp(data.name, ".") == 0 || strcmp(data.name, "..") == 0)
    {
        continue;
    }

    if(data.attrib & _A_SUBDIR)
    {
        removeAll(data.name);
    }

    remove(data.name);

} while(_findnext(handle, &data) != -1);

基本的に、再帰関数は次の疑似コードに従う必要があります。

void deleteAll(path)
{
    for each file in path
    {
        if file is folder
        {
            // empty the folder
            deleteAll(file)
        }

        delete file // whether it is a now-empty folder or a file
    }
}

そうすれば、フォルダーに遭遇したら、すぐにそのフォルダーに入り、その内容を削除してから、その親フォルダーのスコープに戻ります。ここで、フォルダーは空であるため削除できます。

于 2013-06-11T21:05:28.657 に答える