【发布时间】:2018-08-10 18:41:52
【问题描述】:
我有以下问题:
-
如果我传递
boost::filesystem::path::string()的结果与将结果存储在中间字符串变量中,std::regex的行为会有所不同。第一个将返回一个被截断的匹配,后来std::stoull不接受该匹配(抛出 invalid_argument 异常),而第二个完美运行。
请参阅以下解释更多问题的命令:
[nix-shell:~]$ ls -l foo
total 0
-rw-r--r-- 1 amine users 0 Aug 10 16:55 008
-rw-r--r-- 1 amine users 0 Aug 10 15:47 2530047398992289207
[nix-shell:~]$ cat test-1.cpp
#include <iostream>
#include <regex>
#include <string>
#include <boost/filesystem.hpp>
int main() {
std::regex expression{R"(([0-9]+))"};
boost::filesystem::path cacheDir("/home/amine/foo");
for (const auto& entry : boost::filesystem::directory_iterator{cacheDir})
{
std::smatch match;
auto result = std::regex_match(entry.path().filename().string(), match, expression);
std::cout << "Result: " << result << std::endl
<< "Length: " << match[1].length() << std::endl
<< "Match: " << match[1] << std::endl
<< "Filename: " << entry.path().filename().string() << std::endl
<< std::endl;
std::stoull(match[1], 0);
}
return 0;
}
[nix-shell:~]$ g++ -o test1 test-1.cpp -lboost_filesystem -O0 -g
[nix-shell:~]$ ./test1
Result: 1
Length: 19
Match: 98992289207
Filename: 2530047398992289207
terminate called after throwing an instance of 'std::invalid_argument'
what(): stoull
Aborted
[nix-shell:~]$ cat test-2.cpp
#include <iostream>
#include <regex>
#include <string>
#include <boost/filesystem.hpp>
int main() {
std::regex expression{R"(([0-9]+))"};
boost::filesystem::path cacheDir("/home/amine/foo");
for (const auto& entry : boost::filesystem::directory_iterator{cacheDir})
{
std::smatch match;
auto what = entry.path().filename().string();
auto result = std::regex_match(what, match, expression);
std::cout << "Result: " << result << std::endl
<< "Length: " << match[1].length() << std::endl
<< "Match: " << match[1] << std::endl
<< "Filename: " << entry.path().filename().string() << std::endl
<< std::endl;
std::stoull(match[1], 0);
}
return 0;
}
[nix-shell:~]$ g++ -o test2 test-2.cpp -lboost_filesystem -O0 -g
[nix-shell:~]$ ./test2
Result: 1
Length: 19
Match: 2530047398992289207
Filename: 2530047398992289207
Result: 1
Length: 3
Match: 008
Filename: 008
所以我的问题是:
- 为什么直接使用
boost::filesystem::path::string()会截断std::regex的结果。 - 假设匹配变量中的结果被截断也没问题,为什么
std::stoull会抛出异常?
【问题讨论】:
-
您使用的是哪个版本的 gcc?在 libstc++ 中
std::regex的早期实现有缺陷 -
@AlanBirtles 我正在使用 gcc 7.3.0
-
我喜欢制作一个由匹配函数返回的小助手结构,它将字符串和匹配器对象存储在一起。它有时可能效率低下,但使用起来很简单,我可以传入一个临时字符串。
标签: c++ boost std boost-filesystem