I have the following issue where:
std::regex
behaves differently if I pass the result ofboost::filesystem::path::string()
vs storing the result in a intermediate string variable. The first will return a match that is truncated and which is later not accepted bystd::stoull
(throws invalid_argument exception) while the second works perfectly.
See the following commands that explain more the issue:
[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
So my questions are:
- Why is the result of
std::regex
truncated when directly usingboost::filesystem::path::string()
. - And let's assume it's fine if the result in the match variable is truncated, why would
std::stoull
throw an exception with it?