无法将 '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());
结果是
Cannot convert 'int' to 'const char *'
for 循环内部错误。
使用 str.Delete(std::remove(str[0], str.LastChar(), c[i]), str.LastChar());
结果是
Could not find a match for 'remove(wchar_t,wchar_t*,wchar_t)'
for 循环内部错误。
搜索 SO 和网络,据我了解,当本应使用双引号的代码用单引号编写时,通常会收到此错误。我认为这种情况不适用于这种情况。
String
的 return 类型是 Embarcadero 的 UnicodeString
。可以在这里找到详细信息:RAD Studio VCL Reference - UnicodeString Class
在C++Builder中,String
是指System::String
,它是XE8中System::UnicodeString
的别名。
你的代码中有很多错误。
System::String::Delete()
method expects an index and a count as input, but that is not what you are trying to pass to it. You are expecting Delete()
to work like the STL std::wstring::erase()
方法,根本就不是这样。
您没有考虑到 System::String::operator[]
是从 1 开始的。它不是基于 0 的,就像您的代码假设的那样。
System::String::LastChar()
方法 return 是指向字符串中最后一个 UTF-16 编码 Unicode 字符的指针。它不会 return 指向字符串的空终止符的指针,就像您的代码假设的那样。
您正在调用 STL std::remove()
算法,该算法将 iterator
的范围作为输入,将指定值的所有副本移动到范围的末尾,然后 returns 一个新的 iterator
到 "removed" 值已移动到范围内的位置(因此它们可以 erase()
来自拥有 iterator
s 的容器)。您不能按照您尝试的方式混合使用 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();
}
}
我正在使用 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());
结果是Cannot convert 'int' to 'const char *'
for 循环内部错误。
使用
str.Delete(std::remove(str[0], str.LastChar(), c[i]), str.LastChar());
结果是Could not find a match for 'remove(wchar_t,wchar_t*,wchar_t)'
for 循环内部错误。
搜索 SO 和网络,据我了解,当本应使用双引号的代码用单引号编写时,通常会收到此错误。我认为这种情况不适用于这种情况。
String
的 return 类型是 Embarcadero 的 UnicodeString
。可以在这里找到详细信息:RAD Studio VCL Reference - UnicodeString Class
在C++Builder中,String
是指System::String
,它是XE8中System::UnicodeString
的别名。
你的代码中有很多错误。
System::String::Delete()
method expects an index and a count as input, but that is not what you are trying to pass to it. You are expecting Delete()
to work like the STL std::wstring::erase()
方法,根本就不是这样。
您没有考虑到 System::String::operator[]
是从 1 开始的。它不是基于 0 的,就像您的代码假设的那样。
System::String::LastChar()
方法 return 是指向字符串中最后一个 UTF-16 编码 Unicode 字符的指针。它不会 return 指向字符串的空终止符的指针,就像您的代码假设的那样。
您正在调用 STL std::remove()
算法,该算法将 iterator
的范围作为输入,将指定值的所有副本移动到范围的末尾,然后 returns 一个新的 iterator
到 "removed" 值已移动到范围内的位置(因此它们可以 erase()
来自拥有 iterator
s 的容器)。您不能按照您尝试的方式混合使用 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();
}
}