我正试图制作一个程序,输出该文件所在文件夹中所有文件的名称,如果其中两个文件的大小相同,则仅输出一个文件。请注意,我是Boost库的新手,而不是经验丰富的程序员。

这是我想出的:

#include <boost/filesystem.hpp>
#include <iostream>
#include<string>
#include<cstdio>
using namespace std;
void files(string a = ".")
{
bool check = 1;
boost::filesystem::directory_iterator iterator(a);

for (; iterator != boost::filesystem::directory_iterator(); ++iterator)
{

    if (is_directory(iterator->path()))
    {
        files(iterator->path().string());
    }
    else
    {
        boost::filesystem::directory_iterator iterator2(a);
        iterator2 = iterator;
        if (iterator != boost::filesystem::directory_iterator())
        {
            iterator2++;
        }
        for (; iterator2 != boost::filesystem::directory_iterator(); ++iterator2)
        {
            if (file_size(iterator->path()) == file_size(iterator2->path()))
            {
                check = 0;
            }
        }
    }
    if (check == 1)
    {

        cout << (iterator->path().filename()) << endl;
    }
    else
    {
        check = 1;
    }
}
}


int main()
{
files();
}


我试图使其无例外地列出所有文件,并且工作正常,但是当我添加第二个for循环和第二个directory_iterator时,出现了问题。

最佳答案

潜在的问题是boost::filesystem::directory_iterator是输入迭代器,不能保证保持相等性:请参见directory_iterator documentation处的注释。

在实现中,很可能会使用POSIX opendirreaddir接口之类的东西,其中有一个底层的打开文件描述符,从该描述符中依次读取目录条目。

因此,前进iterator2可能与赋值后的iterator1共享相同的基础状态,也很可能会更改iterator1还将返回的内容。

确实,在我的测试平台(Linux,g ++)上,在iterator2循环完成之后,并且iterator2等于最终迭代器,iterator1也等于最终迭代器,并且当程序尝试访问程序时,它会出现段错误。文件名。

简而言之,即使并不清楚情况确实如此,iterator2和iterator1也没有独立的状态。要变通解决此问题,最简单的方法是记录您在std::set(或C ++ 11中的std::unordered_set)中看到的文件大小,并仅在集合尚未包含该文件的情况下打印路径尺寸。

我在这里包括了一个使用std::set来执行此操作的版本。为简单起见,我将递归关系省略到了子目录中。您需要确定是否要忽略与同一子目录中的文件或任何子目录中的文件具有相同大小的文件。

#include <boost/filesystem.hpp>
#include <iostream>
#include <string>
#include <set>

using namespace std;
void files(string a = ".")
{
    boost::filesystem::directory_iterator iterator(a),dir_end;
    std::set<uintmax_t> file_sizes;

    for (; iterator != dir_end; ++iterator) {
        bool emit = true;

        if (!is_directory(iterator->path())) {
            uintmax_t size = file_size(iterator->path());
            if (file_sizes.find(size) == file_sizes.end()) {
                // set does not contain this file size yet.
                file_sizes.insert(size);
            }
            else {
                // set already contains this file size, so don't print path
                emit = false;
            }
        }

        if (emit) {
            cout << (iterator->path().filename()) << endl;
        }
    }
}

int main() {
    files();
}

关于c++ - 调试错误R6010-已调用abort(),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28527744/

10-11 16:15