无法将'int'转换为'const char *'
Cannot Convert 'int' to 'const char *'
我正在使用c++和XE8。给定以下代码:
String __fastcall RemoveCharsFromString(String &str, const String &c)
{
for(unsigned int i=0; i<c.Length(); ++i)
{
str.Delete(std::remove(str[0], str.LastChar(), c[i]), str.LastChar());
}
}
收到的错误:
使用
str.Delete(remove(str[0], str.LastChar(), c[i]), str.LastChar());
导致无法将"int"转换为"const char*"
for循环内部出错。
使用
str.Delete(std::remove(str[0], str.LastChar(), c[i]), str.LastChar());
导致找不到"remove(wchar_t,wchar_t*,wchar_t)"的匹配项
for循环内部出错。
搜索SO和网络,据我所知,当代码使用单引号编写时,通常会出现这种错误,而本应使用双引号。我认为这种情况不适用。
String
的返回类型为Embarcadero的UnicodeString
。详细信息可以在这里找到:RAD Studio VCL参考-UnicodeString类
在C++Builder中,String
指的是System::String
,它是XE8中System::UnicodeString
的别名。
你的代码中有很多错误。
System::String::Delete()
方法需要一个索引和一个计数作为输入,但这并不是你想要传递给它的。你希望Delete()
能像STL std::wstring::erase()
方法一样工作,但事实并非如此。
您没有考虑到System::String::operator[]
是基于1的。它并不像您的代码所假设的那样基于0。
System::String::LastChar()
方法返回一个指针,指向字符串中最后一个UTF-16编码的Unicode字符。它不会像您的代码所假设的那样,返回指向字符串的null终止符的指针。
您正在调用STL std::remove()
算法,该算法以iterator
s的范围作为输入,将指定值的所有副本移到该范围的末尾,然后返回一个新的iterator
,将"已删除"的值移到该区域内的位置(因此它们可以是拥有iterator
s的容器中的erase()
'd)。你不能像你尝试的那样混合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();
}
}