使用 boost::regex 从目录中获取带有某些正则表达式的文件名时出现意外输出
Unexpected output while getting the name of a file with some regex from a directory using boost::regex
我刚刚创建了一个函数 findFile
来查找目录 dir_name
中是否有具有某种模式 file_name_regex
的文件。只需在 Coliru
中进行测试
#include <string>
#include <iostream>
#include <boost/regex.hpp>
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
bool findFile(const std::string & dir_name, const std::string & file_name_regex)
{
fs::path p(dir_name);
if (!exists(p))
return false;
boost::regex file_regex(file_name_regex, boost::regex::basic);
fs::directory_iterator end_itr;
for (fs::directory_iterator itr(p);itr != end_itr; ++itr )
{
if (!fs::is_directory(itr->path()))
{
boost::sregex_iterator it(itr->path().filename().string().begin(),
itr->path().filename().string().end(),
file_regex);
boost::sregex_iterator end;
for (; it != end; ++it){
std::cout << it->str() << std::endl;
}
}
else {
continue;
}
}
return false;
}
int main()
{
findFile("/", "a.out" );
}
使用以下命令编译并运行它:
g++ -std=c++11 -O2 -Wall -lboost_system -lboost_filesystem -lboost_regex main.cpp && ./a.out
它应该打印出来:
a.out
但它给出了意外的输出:
.out
它是基于C++ Regular Expressions with Boost Regex
的解决方案
我也在Coliru中更改了它以进行简单测试:
#include <boost/regex.hpp>
#include <iostream>
#include <string>
int main()
{
std::string text("a.out");
const char * pattern = "a.out";
boost::regex ip_regex(pattern);
boost::sregex_iterator it(text.begin(), text.end(), ip_regex);
boost::sregex_iterator end;
for (; it != end; ++it) {
std::cout << it->str() << "\n";
// v.push_back(it->str()); or something similar
}
}
它打印出预期的单词 a.out
。
所以 我的代码有什么问题?
由于悬挂指针,您获得了 UB。临时 itr->path().filename().string()
在以下语句结束时被销毁:
boost::sregex_iterator it(itr->path().filename().string().begin(),
itr->path().filename().string().end(),
file_regex);
所以 begin()
和 end()
现在指向垃圾。
您需要将临时 string
提升到一个单独的变量中以延长其生命周期:
std::string s = itr->path().filename().string();
boost::sregex_iterator it(s.begin(), s.end(), file_regex);
我刚刚创建了一个函数 findFile
来查找目录 dir_name
中是否有具有某种模式 file_name_regex
的文件。只需在 Coliru
#include <string>
#include <iostream>
#include <boost/regex.hpp>
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
bool findFile(const std::string & dir_name, const std::string & file_name_regex)
{
fs::path p(dir_name);
if (!exists(p))
return false;
boost::regex file_regex(file_name_regex, boost::regex::basic);
fs::directory_iterator end_itr;
for (fs::directory_iterator itr(p);itr != end_itr; ++itr )
{
if (!fs::is_directory(itr->path()))
{
boost::sregex_iterator it(itr->path().filename().string().begin(),
itr->path().filename().string().end(),
file_regex);
boost::sregex_iterator end;
for (; it != end; ++it){
std::cout << it->str() << std::endl;
}
}
else {
continue;
}
}
return false;
}
int main()
{
findFile("/", "a.out" );
}
使用以下命令编译并运行它:
g++ -std=c++11 -O2 -Wall -lboost_system -lboost_filesystem -lboost_regex main.cpp && ./a.out
它应该打印出来:
a.out
但它给出了意外的输出:
.out
它是基于C++ Regular Expressions with Boost Regex
的解决方案我也在Coliru中更改了它以进行简单测试:
#include <boost/regex.hpp>
#include <iostream>
#include <string>
int main()
{
std::string text("a.out");
const char * pattern = "a.out";
boost::regex ip_regex(pattern);
boost::sregex_iterator it(text.begin(), text.end(), ip_regex);
boost::sregex_iterator end;
for (; it != end; ++it) {
std::cout << it->str() << "\n";
// v.push_back(it->str()); or something similar
}
}
它打印出预期的单词 a.out
。
所以 我的代码有什么问题?
由于悬挂指针,您获得了 UB。临时 itr->path().filename().string()
在以下语句结束时被销毁:
boost::sregex_iterator it(itr->path().filename().string().begin(),
itr->path().filename().string().end(),
file_regex);
所以 begin()
和 end()
现在指向垃圾。
您需要将临时 string
提升到一个单独的变量中以延长其生命周期:
std::string s = itr->path().filename().string();
boost::sregex_iterator it(s.begin(), s.end(), file_regex);