gpt4 book ai didi

c++ - 使用 boost::filesystem 和 boost::lexical_cast 从文件名中提取数字

转载 作者:行者123 更新时间:2023-11-30 05:10:45 25 4
gpt4 key购买 nike

请帮忙。我有一个名称为:

X_ab_LOTA123.png

然后我有了这段代码,我可以从文件名中提取数字 123。一切正常。

#include <iostream>
#include <boost/filesystem.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/lexical_cast.hpp>

namespace bfs = boost::filesystem;
namespace ba = boost::adaptors;
using std::string;
using namespace std;

void find(const bfs::path& imageDirPath, const boost::regex& filter)
{
boost::smatch result;
for (auto& entry : boost::make_iterator_range(bfs::directory_iterator(imageDirPath), {})
| ba::filtered(static_cast<bool (*)(const bfs::path &)>(&bfs::is_regular_file))
| ba::filtered([&](const bfs::path &path){ return boost::regex_match(path.filename().string(), result, filter); })
)
{
int32_t num = boost::lexical_cast<int32_t>(result[1]);
cout << "found : " << num << " = " << entry.path().string() << endl;
}
}

int main()
{
const boost::regex defaultFilter( "X_ab_LOTA(\\d{3}).png" );
const bfs::path path(".");
find(path, defaultFilter);
}

结果是:

found : 123 = .\X_ab_LOTA123.png

但是,如果我将文件重命名为:

X_a_LOTA123.png

即我删除了“b”字母,并将过滤器相应地更改为:

const boost::regex defaultFilter( "X_a_LOTA(\\d{3}).png" );

然后程序崩溃了!

我得到了 bad_cast 异常!

我在这里做错了什么?代码很简单。但它仅适用于某些情况,对于其他名称和匹配模式它会崩溃。

请帮忙。

最佳答案

你在那里有未定义的行为。您的范围过滤器有副作用,但在您检查结果之前,副作用可能已被另一个范围条目覆盖。

因此,当 result[1] 可能无效(存在不匹配)或者它甚至可能引用另一条路径时,您正在使用它。更糟糕的是,在这种情况下,第二个过滤器表达式采用的 path const& 引用已经过时(它当时来自 entry 循环变量!)。

最糟糕的是:一旦你编写了 path.filename().string(),你的代码就注定失败了,因为它返回一个临时的,并且它在封闭的完整表达式的末尾被销毁.

Running your code with debug-iterators or with address sanitizers would likely have alerted you about these problems

只是简化:

void find(const bfs::path& imageDirPath, const boost::regex& filter)
{
for (auto entry : bfs::directory_iterator(imageDirPath)) {
if (!is_regular_file(entry))
continue;
auto fname = entry.path().filename().string(); // keep alive longer than result!
boost::smatch result;

if (boost::regex_match(fname, result, filter)) {
int32_t num = boost::lexical_cast<int32_t>(result[1]);
cout << "found : " << num << " = " << entry.path().string() << endl;
}
}
}

事实上,您可能会添加检查匹配组 [1] 是否有效并且在使用它之前是否已成功匹配,因为您的函数不控制所使用的正则表达式。

关于c++ - 使用 boost::filesystem 和 boost::lexical_cast 从文件名中提取数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45515195/

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