This is what I would use, if I had no proper path-parsing alternative:
wxString& remove_trailing_backslashes(wxString& path)
{
auto inb = path.find_last_not_of(L'\\');
if(inb != wxString::npos)
path.erase(inb + 1); //inb + 1 <= size(), valid for erase()
else //empty string or only backslashes
path.clear();
return path; //to allow chaining
}
Notes:
- Unless you're doing something unusual,
wxString
stores wchar_t
s internally, so it makes sense to use wide string and character literals (prefixed with L
) to avoid unnecessary conversions.
- Even in the unusual case when you'd have strings encoded in UTF-8, the code above still works, as
\
is ASCII, so it cannot appear in the encoding of another code point (the L
prefix wouldn't apply anymore in this case, of course).
- Even if you're forced to use
wxString
, I suggest you try to use its std::basic_string
-like interface whenever possible, instead of the wx-specific functions. The code above works fine if you replace wxString
with std::wstring
.
- In support of what VZ. said in his answer, note that all these simplistic string-based solutions will strip
C:\
to C:
, and \
to the empty string, which may not be what you want. To avoid such issues, I would go for the Boost.Filesystem library, which is, as far as I know, the closest to the proposed standard library filesystem functionality (which is not formally part of the standard yet, but very close).
For completeness, here's what it would look like using Boost.Filesystem:
wxString remove_trailing_backslashes(const wxString& arg)
{
using boost::filesystem::path;
static const path dotp = L".";
path p = arg.wc_str();
if(p.filename() == dotp)
p.remove_filename();
return p.native();
}
It's not as efficient as the ad-hoc solution above, mainly because the string is not modified in-place, but more resilient to problems caused by special path formats.