Przetwarzanie Unicode w C ++

107

Jaka jest najlepsza praktyka przetwarzania Unicode w C ++?

Fortepianissimo
źródło

Odpowiedzi:

81
  • Używaj ICU do obsługi swoich danych (lub podobnej biblioteki)
  • W swoim własnym magazynie danych upewnij się, że wszystko jest zapisane w tym samym kodowaniu
  • Upewnij się, że zawsze używasz swojej biblioteki Unicode do przyziemnych zadań, takich jak długość napisów, stan wielkich liter, itp. Nigdy nie używaj wbudowanych bibliotek standardowych, is_alphachyba że jest to pożądana definicja.
  • Nie mogę powiedzieć wystarczająco dużo: nigdy nie iteruj po indeksach a, stringjeśli zależy Ci na poprawności, zawsze używaj do tego biblioteki Unicode.
hazzen
źródło
Chyba że traktujesz dane stringjako dane binarne.
Demi
10

Jeśli nie zależy Ci na wstecznej kompatybilności z poprzednimi standardami C ++, obecny standard C ++ 11 ma wbudowaną obsługę Unicode: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2011 /n3242.pdf

Tak więc naprawdę najlepszą praktyką przy przetwarzaniu Unicode w C ++ byłoby użycie do tego wbudowanych udogodnień. Jednak nie zawsze jest to możliwe w przypadku starszych baz kodu, ponieważ standard jest obecnie tak nowy.

EDYCJA: Aby wyjaśnić, C ++ 11 jest świadomy Unicode, ponieważ ma teraz obsługę literałów Unicode i ciągów Unicode. Jednak biblioteka standardowa ma tylko ograniczoną obsługę przetwarzania i konwersji Unicode. Dla Twoich aktualnych potrzeb może to wystarczyć. Jeśli jednak musisz teraz wykonać duże podnoszenie ciężarów, nadal możesz potrzebować czegoś takiego jak OIOM, aby uzyskać bardziej dogłębne przetwarzanie. Obecnie trwają prace nad kilkoma propozycjami włączenia solidniejszej obsługi konwersji tekstu między różnymi kodowaniami. Domyślam się (i mam nadzieję), że będzie to część następnego raportu technicznego .

eestrada
źródło
Odnośnik do szkicu standardowego dokumentu nie jest zbyt pomocny bez odniesienia do konkretnej sekcji, która opisuje "wbudowaną obsługę Unicode", o której rozmawiasz.
Ben Collins,
1
@BenCollins Sekcja 2.14.5 „Literały ciągów” - omówiono literały ciągów, w tym literały ciągów dla kodowania UTF-8, UTF-16 i UTF-32. Sekcja 22.4.1.4 „Class template codecvt” - omawia klasę codecvt używaną do konwersji między kodowaniem znaków (w tym UTF-8, UTF-16 i UTF-32). W całym dokumencie jest więcej informacji na temat obsługi Unicode, ale wydaje się, że są to najbardziej krytyczne sekcje na ten temat.
eestrada
5

Oto lista kontrolna dotycząca programowania w systemie Windows:

  • Wszystkie ciągi zawarte w _T („mój ciąg”)
  • funkcje strlen () itp. zastąpione przez _tcslen () itd.
  • Użyj LPTSTR i LPCTSTR zamiast char * i const char *
  • Rozpoczynając nowe projekty w Dev Studio, starannie upewnij się, że we właściwościach projektu jest wybrana opcja Unicode.
  • W przypadku ciągów C ++ użyj std :: wstring zamiast std :: string
Adam Pierce
źródło
11
Nie używaj ciągów znaków, znaków i funkcji "T", chyba że zamierzasz tworzyć zarówno kompilacje Unicode, jak i ANSI. Jeśli zamierzasz tworzyć tylko kompilacje Unicode, po prostu rób zwykłe szerokie znaki: L "mój szeroki ciąg" wcslen (L "mój ciąg") itp.
1800 INFORMACJA
Zgadzam się, używaj makr _T tylko wtedy, gdy chcesz mieć ogólny tekst, tj. Możliwość kodowania zarówno dla Unicode, jak i Ascii / MBCS.
1
Jeśli chcesz zrobić zarówno Unicode, jak i ANSI dla łańcuchów C ++, użyj czegoś takiego jak typedef std :: basic_string <TCHAR> tString;
Serge
Ach tak, zawsze robię #ifdef _UNICODE #define tstring std :: wstring #else #define tstring std :: string #endif, ale podoba mi się twój sposób bardziej Serge.
Adam Pierce,
4
Szczerze mówiąc, myślę, że UTF16 to marnotrawstwo, pozostawienie wszystkich kodowań w UTF8 jest prostsze i znacznie bardziej kompatybilne z * nix.
chacham15
3

Spójrz na porównanie ciągów bez uwzględniania wielkości liter w C ++

To pytanie zawiera łącze do dokumentacji firmy Microsoft w formacie Unicode: http://msdn.microsoft.com/en-us/library/cc194799.aspx

Jeśli spojrzysz na lewą stronę nawigacji w witrynie MSDN obok tego artykułu, powinieneś znaleźć wiele informacji dotyczących funkcji Unicode. Jest to część rozdziału poświęconego „Kodowaniu znaków” ( http://msdn.microsoft.com/en-us/library/cc194786.aspx )

Zawiera następujące podsekcje:

  • Model strony kodowej
  • Zestawy znaków dwubajtowych w systemie Windows
  • Unicode
  • Problemy ze zgodnością w środowiskach mieszanych
  • Konwersja danych Unicode
  • Migracja programów opartych na systemie Windows do Unicode
  • Podsumowanie
ine
źródło
2

Chociaż może to nie być najlepsza praktyka dla wszystkich, możesz napisać własne procedury C ++ UNICODE, jeśli chcesz!

Właśnie skończyłem to robić w weekend. Wiele się nauczyłem, chociaż nie gwarantuję, że jest w 100% wolny od błędów, wykonałem wiele testów i wydaje się, że działa poprawnie.

Mój kod podlega nowej licencji BSD i można go znaleźć tutaj:

http://code.google.com/p/netwidecc/downloads/list

Nazywa się WSUCONV i jest dostarczany z przykładowym programem main (), który konwertuje między UTF-8, UTF-16 i standardowym ASCII. Jeśli wyrzucisz główny kod, masz fajną bibliotekę do czytania / pisania UNICODE.

Willow Schlanger
źródło
1

Jak zostało powiedziane powyżej, biblioteka jest najlepszym rozwiązaniem w przypadku korzystania z dużego systemu. Jednak czasami chcesz sobie z tym poradzić (być może dlatego, że biblioteka wykorzystywałaby wiele zasobów, takich jak mikrokontroler). W takim przypadku potrzebujesz prostej biblioteki, z której możesz skopiować części na rzeczy, których faktycznie potrzebujesz.

Przykładowy kod Willowa Schlangera wydaje się dobry (zobacz jego odpowiedź, aby uzyskać więcej informacji).

Znalazłem też inny, który ma mniejszy kod, ale brakuje mu pełnego sprawdzania błędów i obsługuje tylko UTF-8, ale łatwiej było z niego wyjąć części.

Oto lista wbudowanych bibliotek, które wydają się przyzwoite.

Biblioteki osadzone

Paul Hutchinson
źródło