2

私は 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 と Web を検索すると、このエラーは通常、二重引用符を使用する必要があるときに一重引用符でコードを記述したときに受信されることを理解しています。この場合、そのシナリオが当てはまるとは思いません。

の戻り型Stringは Embarcadero のUnicodeStringです。詳細については、RAD Studio VCL リファレンス - UnicodeString クラスを参照してください。

4

1 に答える 1

3

C++Builder では、XE8のエイリアスであるをString参照します。System::StringSystem::UnicodeString

あなたのコードには多くの間違いがあります。

メソッドはSystem::String::Delete()入力としてインデックスとカウントを想定していますが、それは渡そうとしているものではありません。Delete()STLstd::wstring::erase()メソッドのように動作することを期待していますが、そうではありません。

System::String::operator[]1ベースであることを考慮していません。コードが想定しているように、0ベースではありません。

このSystem::String::LastChar()メソッドは、文字列内の最後の UTF-16 エンコード Unicode 文字へのポインターを返します。コードが想定しているように、文字列の null ターミネータへのポインタを返しません。

入力として s の範囲を取り、指定された値のすべてのコピーを範囲の最後にシフトしてから、「削除された」値が範囲内に移動された場所に新しい to を返すSTLstd::remove()アルゴリズムを呼び出しています (したがって、 sを所有するコンテナーから実行できます)。あなたがやろうとしている方法を混ぜることはできません。本当に を使用したい場合は、代わりに次のように使用する必要があります。iteratoriteratorerase()iteratorSystem::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));
    }
}

System::Sysutils::StringReplace()そうは言っても、Embarcadero の RTL には、代わりに使用できる独自の関数があり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);
    }
}

または、文字列で UTF-16 サロゲートを考慮する必要がある場合c(これ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(); 
    }
}
于 2016-05-11T20:24:51.273 に答える