2012-05-13 9 views
5

Mam ten kod:Niewłaściwe zachowanie wielkości() oraz w() w klasie ciąg

string test("żaba"); 

cout << "Word: " << test << endl; 
cout << "Length: " << test.size() << endl; 
cout << "Letter: " << test.at(0) << endl; 

wyjście jest dziwne:

Word: żaba 
Length: 5 
Letter: � 

Jak widać, długość powinna być 4 i list: "ż".

Jak mogę poprawić ten kod, aby działał poprawnie?

+3

Są znaki Unicode, więc powinieneś być za pomocą szerokich wersje tych funkcji/typów danych: 'std :: wstring' i' std: : wcout'. –

+0

Podstawowe czytanie: http://www.joelonsoftware.com/articles/Unicode.html –

+0

spójrz na to: http://en.cppreference.com/w/cpp/string/multibyte –

Odpowiedz

5

std::string na non-Windows jest zazwyczaj używany do przechowywania ciągów UTF8 (jako domyślnego kodowania na najbardziej rozsądnych systemów operacyjnych tej stronie 2010), ale jest to „głupi” kontener, że w tym sensie, że nie wie, lub troszcz się o bajty, które przechowujesz. Będzie działał na czytanie, przechowywanie i pisanie; ale nie do manipulacji ciągami.

Musisz użyć doskonałego i dobrze utrzymanego IBM ICU: International Components dla Unicode. Jest to biblioteka C/C++ dla * nix lub Windows, w której przeprowadzono mnóstwo badań, aby zapewnić biblioteki ciągów kulturowych, w tym rozróżnianie wielkości liter, które są zarówno szybkie, jak i dokładne.

Kolejny dobry projekt to łatwiejsze, aby przełączyć się na C++ deweloperów jest UTF8-CPP

+0

"std :: string na non-Windows jest UTF8" - Nie, wcale nie! 'std :: string' nie dba o kodowanie znaków, po prostu zarządza tablicami znaków typu" char ". –

+0

Tak, nie w tym sensie. Zaktualizuję. –

+0

Upuść referencję UTF8! Chociaż 'std :: string' może * posiadać * te łańcuchy, będzie działać tylko z kodowaniem jednoznakowym. Nawet "długość()" nie jest poprawna. Jaki jest sens używania 'std :: string' do przechowywania zakodowanej w standardzie wielobajtowym UTF-8, jeśli nie możesz nic z nią zrobić? Równie dobrze można użyć 'std :: vector '. –

6

Twoje pytanie nie wspomina o kodowaniu, więc zamierzam zrobić ukłucie w ciemności i powiedzieć, że to jest powód.

Pierwszy etap działania: przeczytaj The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!).

Po tym stanie się jasne, że coś takiego jak "nagi ciąg" nie istnieje - każdy ciąg jest zakodowany w jakiś sposób. W twoim przypadku wygląda to tak, jakbyś używał łańcucha zakodowanego w UTF-8 z znakami diakrytycznymi, w takim przypadku, tak, długość łańcucha jest (poprawnie) zgłaszana jako 5 , a pierwszy punkt kodu może nie można drukować na platformie.


1) Zauważ, że string::size liczy bajtów (= char s), postacie nie logiczne, a nawet punkty kodowe.

+0

+1 za link, oczywiście! –

Powiązane problemy