5

今、C プログラムで libunistring を使用しようとしています。UTF-8 文字列を処理する必要があり、そのために libunistring ライブラリの u8_strlen() 関数を使用しました。
コード例:

void print_length(uint8_t *msg) {
    printf("Default strlen: %d\n", strlen((char *)msg));
    printf("U8 strlen: %d\n", u8_strlen(msg));
}

(キリル文字、utf-8 エンコーディング) で呼び出すprint_length()と想像してみてください。12 (6 文字 * 1 文字あたり 2 バイト) が返され、 6 (6 文字だけ) が返されるはずですmsg = "привет"strlen()u8_strlen()

しかし、興味深い結果が得られました。

Default strlen: 12
U8 strlen: 12

この後、u8_strlen の実現を調べようとしたところ、次のコードが見つかりました。

size_t
u8_strlen (const uint8_t *s)
{
    return strlen ((const char *) s);
}

私は疑問に思っています、それはバグですか、それとも正解ですか?正しいとすれば、なぜですか?

4

2 に答える 2

7

これは意図した動作だと思います。

libunistring マニュアルには次のように書かれています。

size_t u8_strlen (const uint8_t *s)

s の単位数を返します。

また、マニュアルでは、この「ユニット」が何であるかを定義しています。

タイプ「uint8_t *」によるUTF-8文字列。単位はバイト (uint8_t) です。

u8_strlen標準以上のことは何もしていないにもかかわらず、関数にラベルを付ける理由strlenは、ライブラリがUTF-16 および UTF-32 文字列をそれぞれ操作するためのu16_strlenとを持っているためだと思います (0x0000 までの 2 バイト単位の数をカウントします)。 u32_strlen、および 0x00000000 までの 4 バイト単位) であり、u8_strlen単に完全を期すために含まれています。

ただし、 GNU gnulibmbslenには、おそらくあなたが望むことを行うものが含まれています:

mbslen 関数: 文字列内のマルチバイト文字の数を決定します。

于 2013-09-26T16:25:47.963 に答える
0

ベリーの答えに加えて、C標準では1文字に8ビットを超えることが許可されていることに注意してください。次にstrlen()、8ビットブロックではなくcharで長さを返すため、返されるものの一部になりu8_strlen()ます(または返す必要があります-あなたが示した実装は明らかに機能せず、 と同じ答えを返しますstrlen())。

于 2013-09-26T18:35:55.490 に答える