gpt4 book ai didi

c++ - 带有 boost directory_iterator 的 Max_element

转载 作者:行者123 更新时间:2023-11-30 02:53:30 24 4
gpt4 key购买 nike

我正在使用 boost 的文件系统和 std::max_element() 来查找给定目录中名称最长的文件:

#include <iostream>
#include <iterator>
#include <algorithm>
#include <string>
#include <boost/filesystem.hpp>
using namespace std;
using namespace boost::filesystem;

bool size_comp( directory_entry de1, directory_entry de2 )
{
return de1.path().string().size() < de2.path().string().size();
}

int main(int argc, char* argv[])
{
path p (argv[1]); // p is a path to a directory

directory_iterator itr (p);
directory_iterator itr_end;
directory_iterator itr_max=::max_element(itr,itr_end,size_comp);
int max_size = itr_max->path().string().size();
cout << "Longest file name: " << itr_max->path() << " has "
<< max_size << " characters" << endl;
return 0;
}

对于包含文件 cat.dat、mouse.dat、elephant.dat 的目录 Animals,输出为:

Longest file name: Animals/mouse.dat has 17 characters

这既不是最长的也不是最短的文件名。上面的代码有什么问题?

最佳答案

boost::filesystem::directory_iterator 股份状态。实现声明实现由 boost::shared_ptr 管理允许 InputIterators 所需的浅拷贝语义。因此,当一个算法,例如 std::max_element , 遍历 [first,last) ,结果迭代器随着 first 的每次增量而间接修改,因为结果迭代器将与 first 共享状态.

要解决此问题,请考虑存储 boost::filesystem::directory_entry 贯穿整个算法。例如,可以构造一个 std::vector<directory_entry>来自directory_iterator范围,然后将 vector 传递给 std::max_element .或者,手动编写算法可能更容易。

这是一个完整的示例,展示了两种方法,在当前目录上运行。

#include <algorithm> // std::copy, std::max_element
#include <iterator> // std::back_inserter
#include <iostream> // std::cout, std::endl
#include <vector>
#include <utility> // std::make_pair

#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>

namespace fs = boost::filesystem;

bool size_comp(const fs::directory_entry& lhs,
const fs::directory_entry& rhs)
{
return lhs.path().string().size() < rhs.path().string().size();
}

/// @brief Finds max by copying all directory entries.
fs::directory_entry max_full_copy(
fs::directory_iterator first,
fs::directory_iterator last)
{
// Extract directory_entries from directory_iteartor.
std::vector<fs::directory_entry> entries;
std::copy(first, last, std::back_inserter(entries));
// Find max element.
return *std::max_element(entries.begin(), entries.end(), &size_comp);
}

/// @brief Finds max by only storing a copy of the max entry.
fs::directory_entry max_single_copy(
fs::directory_iterator first,
fs::directory_iterator last)
{
fs::directory_entry result;
BOOST_FOREACH(fs::directory_entry& current, std::make_pair(first, last))
{
if (size_comp(result, current))
result = current;
}
return result;
}

int main()
{
std::cout << max_full_copy(fs::directory_iterator("."),
fs::directory_iterator()) << "\n"
<< max_single_copy(fs::directory_iterator("."),
fs::directory_iterator()) << std::endl;
}

一个示例运行输出:

[tsansbury@localhost tmp]$ lsfile_four  file_one  file_three  file_two[tsansbury@localhost tmp]$ ../a.out "./file_three""./file_three"

关于c++ - 带有 boost directory_iterator 的 Max_element,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17947673/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com