'\0' バイトは、シフト状態 (5.2.1.2 マルチバイト文字) に関係なくヌル ワイド文字に変換する必要がありmbrtowc()
、ワイド ヌル文字 (7.24.6.3.2 /3 mbrtowc 関数) を呼び出すと、 が指す にmbrtowc( NULL, "", 1, ps)
格納されているシフト状態がリセットさmbstate_t
れps
ます。mbrtowc( NULL, "", 1, NULL)
ライブラリの内部オブジェクトを使用するために が呼び出されると、mbstate_t
初期状態にリセットされます。標準の関連ビットの引用については、回答の最後を参照してください。
私は、C 標準のマルチバイト変換関数について特別な経験があるわけではありません (この種の経験では、変換に Win32 API を使用しています)。
mbrtowc()
0バイトで短くカットされた「不完全な文字」を処理する場合(size_t)(-1)
、無効なマルチバイト文字を示すために返されます(したがって、説明する危険な状況を検出します)。その場合、変換/シフト状態は指定されていません (そして、基本的にその文字列にうんざりしていると思います)。変換が試みられたが を含むマルチバイトの「シーケンス」'\0'
は無効であり、後続のデータで有効になります。'\0
' が変換されたシーケンスの一部であることが意図されていない場合、処理に使用できるバイト数に含まれるべきではありません。
部分的なマルチバイト文字 (ネットワーク ストリームなど) の追加の後続のバイトを取得する可能性がある状況にある場合、部分的なマルチバイト文字n
に渡したものに 0 バイトを含めないでください。(size_t)(-2)
戻ってきた。この場合、'\0'
部分変換の途中でしばらく経過すると、エラーが発生したという事実が失われ、副作用として使用中のmbstate_t
状態がリセットされます (使用中の状態が自分のものであるか、使用されている内部のものであるかに関係なく)。に NULL ポインターを渡しましたps
)。私は本質的にここであなたの質問を言い直していると思います。
ただし、この状況を検出して処理することは可能だと思いますが、残念ながら、自分で状態を追跡する必要があります。
#define MB_ERROR ((size_t)(-1))
#define MB_PARTIAL ((size_t)(-2))
// function to get a stream of multibyte characters from somewhere
int get_next(void);
int bar(void)
{
char c;
wchar_t wc;
mbstate_t state = {0};
int in_partial_convert = 0;
while ((c = get_next()) != EOF)
{
size_t result = mbrtowc( &wc, &c, 1, &state);
switch (result) {
case MB_ERROR:
// this multibyte char is invalid
return -1;
case MB_PARTIAL:
// do nothing yet, we need more data
// but remember that we're in this state
in_partial_convert = 1;
break;
case 1:
// output the competed wide char
in_partial_convert = 0; // no longer in the middle of a conversion
putwchar(wc);
break;
case 0:
if (in_partial_convert) {
// this 'last' multibyte char was mal-formed
// return an error condidtion
return -1;
}
// end of the multibyte string
// we'll handle similar to EOF
return 0;
}
}
return 0;
}
理想的な状況ではないかもしれませんが、完全に壊れていて使えないわけではないことを示していると思います。
規格の引用:
5.2.1.2 マルチバイト文字
マルチバイト文字セットには、状態依存のエンコーディングが含まれる場合があります。この場合、マルチバイト文字の各シーケンスは初期シフト状態で始まり、特定のマルチバイト文字がシーケンス内で検出されると、他のロケール固有のシフト状態に入ります。初期シフト状態の間、すべてのシングルバイト文字は通常の解釈を保持し、シフト状態を変更しません。シーケンス内の後続のバイトの解釈は、現在のシフト状態の関数です。
すべてのビットがゼロのバイトは、シフト状態に関係なくヌル文字として解釈されます。
- すべてのビットが 0 のバイトは、マルチバイト文字の 2 番目以降のバイトには出現しません。
7.24.6.3.2/3 mbrtowc 関数
対応するワイド文字がヌル ワイド文字の場合、記述されている結果の状態は初期変換状態です。