Reputation: 5902
I am working on an application written in C++ that primarily uses wxWidgets for its objects. Now, suppose I have the following wxString variable:
wxString path = "C:\\Program Files\\Some\\Path\\To\\A\\Directory\\";
Are there any ways to remove the trailing slashes? While wxString provides a Trim()
method, it only applies to whitespace characters. I could think of converting the string to another string type and perform the stripping there and switch back to the wxString type (it is essential that I use the wxString type) but if there is a less convoluted way of doing things, I'd prefer that.
Upvotes: 3
Views: 3841
Reputation: 9317
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:
wxString
stores wchar_t
s internally, so it makes sense to use wide string and character literals (prefixed with L
) to avoid unnecessary conversions.\
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).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
.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.
Upvotes: 2
Reputation: 5902
My use case actually also considers scenarios without trailing slashes.
I came up with two solutions. The first makes use of regular expression:
wxRegEx StripRegex("(.+?)\\\\*$", wxRE_ADVANCED);
if (StripRegex.Matches(path))
{
path = StripRegex.GetMatch(path,1);
}
The second, as @catalin suggested, uses RemoveLast
:
while (path.EndsWith("\\"))
{
path.RemoveLast();
}
Edit: Using @VZ's suggestion, I came up with the following:
// for some reason, the 'Program Files' part get's taken out in the resulting string
// so I have to first replace the double slashes
path.Replace("\\\\","\\");
path = wxFileName::DirName(path).GetPath();
Upvotes: 1
Reputation: 22688
The others have mentioned how this can be achieved using wxString
methods, however I would strongly advise using an appropriate class, i.e. either wxFileName or, maybe, std::filesystem::path
, for working with paths instead of raw strings. E.g. to get a canonical representation of the path in your case I would use wxFileName::DirName(path).GetFullPath()
.
Upvotes: 4