2

我正在开发一个用 C++ 编写的应用程序,该应用程序主要使用 wxWidgets 作为其对象。现在,假设我有以下 wxString 变量:

wxString path = "C:\\Program Files\\Some\\Path\\To\\A\\Directory\\";

有什么方法可以删除尾部的斜杠吗?虽然 wxString 提供了一种Trim()方法,但它只适用于空白字符。我可以考虑将字符串转换为另一种字符串类型并在那里执行剥离并切换回 wxString 类型(我必须使用 wxString 类型)但是如果有一种不那么复杂的做事方式,我会更喜欢那。

4

4 回答 4

4

其他人已经提到如何使用wxString方法来实现这一点,但是我强烈建议使用适当的类,即wxFileName或者,也许,std::filesystem::path使用路径而不是原始字符串。例如,为了在您的情况下获得路径的规范表示,我将使用wxFileName::DirName(path).GetFullPath().

于 2015-03-26T12:35:51.520 回答
2

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_ts 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.

于 2015-03-26T16:34:20.450 回答
2

path.erase(path.end() - 1);

或者

path.RemoveLast();

于 2015-03-26T09:09:58.890 回答
1

我的用例实际上还考虑了没有斜杠的场景。

我想出了两个解决方案。第一个使用正则表达式:

wxRegEx StripRegex("(.+?)\\\\*$", wxRE_ADVANCED);
if (StripRegex.Matches(path))
{
  path = StripRegex.GetMatch(path,1);
}

第二个,正如@catalin 建议的那样,使用RemoveLast

while (path.EndsWith("\\"))
{
  path.RemoveLast();
}

编辑:使用@VZ的建议,我想出了以下内容:

// 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();
于 2015-03-26T11:07:23.903 回答