Próbuję zaimplementować obsługę tekstów w systemie Windows z zamiarem przeniesienia na platformę Linux. Idealnym rozwiązaniem byłoby wspieranie języków międzynarodowych w jednolity sposób, ale wydaje się, że nie jest to łatwe do zrealizowania przy rozpatrywaniu dwóch wspomnianych platform. Spędziłem dużo czasu czytając UNICODE, UTF-8 (i inne kodowania), widechary i takie i oto, co do tej pory zrozumiałem:UNICODE, UTF-8 i Windows Mess
UNICODE, jako standard, opisuje zestaw znaków, które można mapować i kolejności, w jakiej występują. Odnoszę się do tego jako "co": UNICODE określa , co będzie dostępne pod adresem.
UTF-8 (i inne kodowania) określ jak: Jak każda postać będzie reprezentowana w formacie binarnym.
Teraz, w systemie Windows, początkowo zdecydowali się na kodowanie UCS-2, ale to nie spełniło wymagań, więc UTF-16 to to, co mają, a także, w razie potrzeby, wiele znaków.
Więc tutaj jest delemma:
- Okna wewnętrznie tylko robi UTF-16, więc jeśli chcesz obsługiwać znaki międzynarodowe jesteś zmuszony do przejścia na ich widechar wersjach używać OS nazywa się odpowiednio. Wydaje się, że nie ma żadnego wsparcia dla wywoływania czegoś takiego jak CreateFileA() z wielobajtowym ciągiem znaków UTF-8 i sprawiają, że wygląda on prawidłowo. Czy to jest poprawne?
- W języku C istnieją niektóre wielobajtowe funkcje wspierające (_mbscat, _mbscpy, itp.), Jednak w oknach typ znaku jest zdefiniowany jako unsigned char * dla tych funkcji. Biorąc pod uwagę, że seria funkcji mbs nie jest kompletnym zbiorem (tzn. Nie ma _bbstol do konwertowania wielobajtowych łańcuchów na długie, na przykład), jesteś zmuszony do korzystania z niektórych wersji char * wersji funkcji uruchomieniowych, co prowadzi do problemów z kompilatorem z powodu podpisanej/niepodpisanej różnicy między tymi funkcjami. Czy ktoś nawet z nich korzysta? Czy po prostu robisz duży stos rzucania, aby obejść błędy?
- W C++, std :: string zawiera iteratory, ale są one oparte na char_type, a nie na punktach kodu. Więc jeśli zrobię ++ na std :: string :: iterator, otrzymam następny char_type, a nie następny punkt kodowy. Podobnie, jeśli wywołasz std :: string :: operator [], otrzymasz odwołanie do char_type, który ma wielki potencjał, aby nie być kompletnym punktem kodowym. Więc w jaki sposób jeden iterować std :: string według punktu kodowego? (C ma funkcję _mbsinc()).
Nie "wielobajtowe w razie potrzeby". To po prostu "wielobajtowe". Nie wiesz, czy jest to "konieczne", dopóki nie zaczniesz go przetwarzać. –
Oto mój [post of mine] (http://stackoverflow.com/questions/6300804/wchars-encodings-standards-and -portability) na ten temat; może cię to interesuje. Dla (3) skonwertuj dane do UTF-32 (idealnie przechowywane w 'char32_t'), a następnie kod wskazuje równe elementy ciągów. –
Należy pamiętać, że istnieje kilka uzasadnionych powodów do iteracji ciągu znaków Unicode za pomocą punktów kodowych, ponieważ grafem może być reprezentowany przez wiele punktów kodowych (z których każdy może zawierać wiele jednostek kodu w UTF-8 lub UTF-16, ale w przypadku wiele praktycznych celów to ten sam problem dwa razy). Normalizacja to jeden uzasadniony powód, kodowanie do UTF-8 jest kolejnym, ale są to rzeczy, do których i tak możesz użyć biblioteki. –