3.7 マルチバイト文字列
RWCString クラスは、制限付きで各種のアルファベットを表わすマルチバイト文字列に対応しています (16.1 節参照)。マルチバイト文字は 2 バイト以上で構成されるので、文字列のバイト単位の長さは、文字列の実際の文字数と同じかそれ以上になる可能性があります。
RWCString にマルチバイト文字が含まれている場合は、文字数を返すメンバ関数 mbLength() を使ってください。ただし、RWCString にマルチバイト文字が含まれていないことがわかっている場合は、length() と mbLength() の結果は同じになるので、より速い length() の使用をお勧めします。次に、定義した Sun でマルチバイト文字を使う例を示します。
RWCString Sun("\306\374\315\313\306\374");
cout << Sun.length(); // "6" を出力
cout << Sun.mbLength(); // "3" を出力
Sun 内の文字列は、マルチバイトコードセットの一種である EUC (Extended UNIX Code) で表した漢字の「日曜日」です。EUC では、1 文字は 1 から 4 バイトの長さになります。この例では、文字列 Sun は6 バイトですが、3 文字から構成されています。
一般的に、マルチバイトの 2 番目のバイト以降はヌルの可能性があります。つまり、文字列のバイト単位の長さは、strlen() によって得られる長さと必ずしも一致するとは限りません。内部的に、RWCString は埋め込みヌルを無視します[1]。つまり、ヌルバイトを使用する文字セットに対して問題なく使用できます。また、RWCString::data() が常にヌルで切られた文字列を返すのに対し、文字列中にヌルが残っている可能性があることにも留意してください。実際にどのように動作するかは、次のプログラムに要約されています。
#include <rw/cstring.h>
#include <rw/rstream.h>
#include <string.h>
main() {
RWCString a("abc"); // 1
RWCString b("abc\0def"); // 2
RWCString c("abc\0def", 7); // 3
cout << a.length(); // "3" を出力
cout << strlen(a.data()); // "3" を出力
cout << b.length(); // "3" を出力
cout << strlen(b.data()); // "3" を出力
cout << c.length(); // "7" を出力
cout << strlen(c.data()); // "3" を出力
return 0; }
上記例では、2 つの異なるコンストラクタが使用されています。// 1 と // 2 のコンストラクタは、ヌルで区切られた文字列である const char* というただ 1 つの引数を持ちます。引数が 1 つであるため、これは型変換に使用できます (ARM 12.3.1)。結果の長さは、ヌルの前のバイト数で決定されます。// 3 のコンストラクタは、const char* と文字列の長さを引数として持っています。コンストラクタは、埋め込みヌルを含め、すべてのバイトをコピーします。
RWCString のバイト単位の長さは、常に RWCString::length() によってわかります。文字列には埋め込みヌルが含まれている可能性があるため、この長さは必ずしも strlen() による結果と一致するとは限りません。
インデックス付けおよびその他の演算子、基本的に size_t 型の引数を使用する関数は、すべてバイト単位で機能することを覚えておいてください。つまり、これらの演算子はマルチバイト文字列を含む RWCString では、機能しません。
注釈
- ^ ただし、マルチバイト文字列を転送するシステム関数は無視をしない可能性があります。RWCString は単にこのような関数を呼び出し、変換するだけです。