在 C++Builder 中,String
指的是XE8System::String
中的别名。System::UnicodeString
您的代码中有很多错误。
该System::String::Delete()
方法需要一个索引和一个计数作为输入,但这不是您要传递给它的内容。您期望Delete()
像 STLstd::wstring::erase()
方法一样工作,但事实并非如此。
您没有考虑到System::String::operator[]
基于 1 的情况。它不是基于 0 的,就像您的代码所假设的那样。
该System::String::LastChar()
方法返回指向字符串中最后一个 UTF-16 编码的 Unicode 字符的指针。它不会像您的代码所假设的那样返回指向字符串的空终止符的指针。
您正在调用将 s 范围作为输入的 STLstd::remove()
算法,将iterator
指定值的所有副本移动到范围的末尾,然后返回一个新iterator
的到“已删除”值已移动到范围内的位置(所以它们可以erase()
从拥有 s 的容器中获取iterator
)。你不能混合你试图做的方式System::String::Delete()
。std::remove()
如果你真的想使用std::replace()
,你需要像这样使用它:
String __fastcall RemoveCharsFromString(String &str, const String &c)
{
for(int i = 1; i <= c.Length(); ++i)
{
const Char *start = str.c_str();
const Char* end = start + str.Length();
Char* ptr = std::replace(start, end, c[i]);
str.Delete(1 + std::distance(start, ptr), std::distance(ptr, end));
}
}
话虽如此,Embarcadero 的 RTL 有自己的System::Sysutils::StringReplace()
功能,您可以使用它来代替std::replace()
:
#include <System.SysUtils.hpp>
String __fastcall RemoveCharsFromString(String &str, const String &c)
{
for(int i = 1; i <= c.Length(); ++i)
{
str = StringReplace(str, c[i], L"", TReplaceFlags() << rfReplaceAll);
}
}
c
或者,如果您需要在字符串中考虑 UTF-16 代理项(std::remove()
不考虑):
#include <System.SysUtils.hpp>
#include <System.Character.hpp>
String __fastcall RemoveCharsFromString(String &str, const String &c)
{
int i = 1;
while (i <= c.Length())
{
String chr;
if (IsSurrogatePair(c, i))
chr = c.SubString(i, 2);
else
chr = c.SubString(i, 1);
str = StringReplace(str, chr, L"", TReplaceFlags() << rfReplaceAll);
i += chr.Length();
}
}