0

我正在尝试从我的命令行解释器中删除所有文件和子目录。当调用 rmdir -s newFolder 时,我调用了一个函数 removeAll,它遍历所有文件和子文件夹并删除所有文件。

例如,如果我想删除文件 newFolder,我删除所有文件并进入 newFolder1。我删除 newFolder1 中的所有文件并进入 newFolder2 并删除所有文件。所以现在我在 newFolder 2 中,newFolder、newFolder1 和 newFolder2 是空的。

我的问题是如何递归备份并删除这 3 个空文件夹。我已经调试并为此工作了几个小时,但我就是不明白。谢谢

这个函数会成功删除一个空文件夹,否则调用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 回答