使用boost :: filesystem和boost :: lexical_cast

时间:2017-08-04 20:42:01

标签: c++ boost

请帮忙。 我有一个名字的文件:

  

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);
}

结果是:

  

发现:123 =。\ X_ab_LOTA123.png

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

  

X_a_LOTA123.png

即。我删除'b'字母,我也相应地更改过滤器:

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

然后程序崩溃了!

我得到了bad_cast异常!

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

请帮忙。

1 个答案:

答案 0 :(得分:1)

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

因此,当result[1]可能无效(存在不匹配)或甚至可能引用其他路径时,您正在使用path const&。更糟糕的是,在这种情况下,第二个过滤器表达式所引用的entry引用已经过时(它当时是从path.filename().string()循环变量派生的!)。

最糟糕的是:一旦你编写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]

实际上,您可以添加匹配组const有效并且在使用之前已成功匹配的检查,因为您的函数不能控制使用的正则表达式。