I have a std::wstring fName
filename for which I'd like to test if it has a .txt extension. This works:
return ((fName.length() >= 4) && (0 == fName.compare(fName.length() - 4, 4, L".txt")));
but it's case sensitive, which I don't want: I need blah.tXt
and hello.TXT
to be both accepted.
This should work as a case-insensitive version:
std::wstring ext = L".txt";
wstring::const_iterator it = std::search(fName.end() - 4, fName.end(), ext.begin(), ext.end(),
[](wchar_t ch1, wchar_t ch2) { return tolower(ch1) == ch2; });
// no need tolower(ch2) because the pattern .txt is already lowercase
return (it != str1.end());
but the std::search
is probably far from optimal because it searches if it contains a pattern (anywhere in the origin string), and here I only need to compare character by character.
As I need to test this for millions of filenames, how can I improve the performance to check if a filename has an extension (case-insensitive) .txt
?
I don't want the easy solution :
let's lowercase the
fName
in a new variable (or even lowercase just the 4 last char offName
)then compare
because this would require new variables, memory, etc. Can I compare in place, with a custom predicate [](wchar_t ch1, wchar_t ch2) { return tolower(ch1) == ch2; })
?
Note: I'm not looking for Boost solutions, nor solutions like this one Case insensitive string comparison in C++ or many similar questions which are not optimized for performance.