1

操作に問題がありますstring。まず、次のことを検討してくださいstring

string s1 = "Graveworm";
string s2 = "Motörhead"; //the best of the best, just to say...

ご覧のとおり、それぞれに 9 つcharの s があります。はい..しかし、いいえ.... pop_back()"é" のようなアクセント付きの文字の場合、 pop_back()2 つcharの s が必要だからです。

charだから今、私がしなければならない数を知る方法がありpop_back()、それを覚えてs1s2コードに書かれています。

注 :: この質問を書いているときに、考えられる方法が思い浮かびます。さて、私はこれを試しました:

if(s->size()>0){
         int size = s->size();
         for(i=size; i > size-1 ;i--){
           s->pop_back();
         }

期待どおりに動作しない

4

3 に答える 3

3

特に最新の Linux では、ほとんどの (すべて?) テキストおよびコード エディター"Motörhead"は、引用符の間に 10 バイトを入れてファイルに保存します。ソースコードファイルを試してみるhexdumpと、次のようなものが表示されます

00000050  32 20 3d 20 22 4d 6f 74  c3 b6 72 68 65 61 64 22  |2 = "Mot..rhead"|

を使用すると、C++11 で移植可能な方法でこの動作を実現できます。u8"Motörhead"

各マルチバイト文字のバイト数を調べることはほとんど必要ありませんが、本当に必要な場合は、std::mblenstd::mbrlenおよび関連する関数が役立ちます。

于 2013-07-02T21:59:42.907 に答える
2

ほとんどの Linux ディストリビューションは、非 ASCII 文字にUTF-8エンコーディングを使用します。UTF-8 には、先頭以外のすべてのバイトが のビット パターンを持つというプロパティがある10xxxxxxため、UTF-8 文字全体をポップする 1 つの方法は次のようになります。

// Note: How this gets compiled depends on your compiler's input character set.
// For GCC, see the -finput-charset and -fexec-charset compiler options.
std::string s = "Motörhead";

while (s.size() > 0)
{
    char c = s.back();
    s.pop_back();

    // If we found an initial character, we're done
    if ((c & 0xC0) != 0x80)
        break;
}

0xxxxxxxこれは、最初の文字 (またはの最初のビット パターンを持つもの11xxxxxx) が見つかるまで、文字をポップすることによって機能します。また、文字列の形式が正しくなく、実際には有効な UTF-8 でない場合に、未定義の動作を回避して回避するためのセーフティ ネットもあります。

ただし、このコードはターゲット環境を想定していることに注意してください。これを UTF-8 以外の環境で実行する場合は、このコードを使用する前に文字列が UTF-8 に変換されていること、および出力される前にターゲット環境のエンコーディングに変換されていることを確認する必要があります (例:コンソールに出力されます)。そうしないと、驚くべき方法で失敗します (多くの場合、ある種のmojibakeで)。

于 2013-07-02T21:59:53.873 に答える
2

エンコーディングが UTF-8 の場合、コーディングを利用して、コードポイントの最初のバイトに到達したことを知ることができます。それは、バイト値が< 128(ASCII 範囲) の場合、または と の間の場合0xc0です0xff

残念ながら、これはコードポイントをポップしたときにのみ通知します。文字の組み合わせを検討している場合、実際の文字は複数のコードポイントで構成される場合があります。

于 2013-07-02T22:00:10.463 に答える