2013-09-26 11 views
5

Właśnie teraz próbuję użyć libunistring w moim programie c. Muszę przetworzyć ciąg znaków UTF-8, a dla niego użyłem funkcji u8_strlen() z biblioteki libunistring.
przykład Kod:libunistring u8_strlen() równa się strlen()?

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

Wystarczy wyobrazić sobie, że nazywamy print_length() z msg = "привет" (cyrylica, kodowanie UTF-8). Oczekiwalem, ze strlen() powinien zwrocic 12 (6 liter * 2 bajty na liter), a u8_strlen() powinien zwrocic 6 (tylko 6 liter).

Ale otrzymaliśmy wyniki ciekawy:

Default strlen: 12 
U8 strlen: 12 

Po tym ja próbowałem do wyszukiwania u8_strlen realizację, i znaleźć ten kod:

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

Zastanawiam się, czy to bug czy to jest poprawna odpowiedź? Jeśli to prawda, dlaczego?

Odpowiedz

7

Uważam, że jest to zamierzone zachowanie.

The libunistring manual mówi, że:

u8_strlen size_t (const uint8_t * s)

Zwraca liczbę jednostek s.

Również w instrukcji, to określa, co to "jednostka" oznacza:

UTF-8 ciągi, poprzez typu „uint8_t *”. Jednostki są bajtami (uint8_t).

Wierzę, że powodem, dla którego etykieta funkcję u8_strlen mimo że nie robi nic więcej niż standardową strlen jest to, że biblioteka ma również u16_strlen i u32_strlen do pracy na UTF-16 i UTF-32 strun, odpowiednio (co policz liczbę 2-bajtowych jednostek aż do 0x0000 i 4-bajtowych jednostek aż do 0x00000000) i zawierają one po prostu u8_strlen dla kompletności.

GNU gnulib obejmuje jednak mbslen który prawdopodobnie robi to, co chcesz:

mbslen funkcja: Określić liczbę znaków wielobajtowych w ciąg.

0

Oprócz odpowiedzi Berry, chciałbym zauważyć, że standard C pozwala na to, że w znaku znajduje się więcej niż 8 bitów. Wtedy strlen() zwróci długość w char, a nie w blokach 8-bitowych, więc będzie to ułamek tego, co zwraca u8_strlen() (lub powinien powrócić - implementacja, którą pokazałeś, oczywiście nie zadziałałaby i daje taką samą odpowiedź jak strlen()) .