Гарантируется ли кодирование строки широких символов, начинающейся с L, например L, "Hello World", в кодировке Unicode?

Недавно я попытался получить полное представление о том, какие шаги необходимо предпринять для создания независимых от платформы приложений C++, поддерживающих юникод. Что меня смущает, так это то, что большинство howtos и прочего выравнивают кодировку символов (т.е. ANSI или Unicode) и тип символов (char или wchar_t). Как я узнал до сих пор, это разные вещи, и может существовать последовательность символов, закодированная в Unicode, но представленная как std::string, а также последовательность символов, закодированная в ANSI, но представленная как std::wstring, верно?

Поэтому возникает вопрос: дает ли стандарт C++ какие-либо гарантии о кодировании строковых литералов, начиная с L или он просто говорит, что он имеет тип wchar_t с кодировкой символов для конкретной реализации?

Если такой гарантии нет, значит ли это, что мне нужна какая-то внешняя система ресурсов для обеспечения строковых литералов не ASCII для моего приложения независимым от платформы способом? Какой способ для этого предпочтителен? Система ресурсов или правильная кодировка исходных файлов плюс правильные параметры компилятора?

3 ответа

Решение

L Символ перед строковым литералом просто означает, что каждый символ в строке будет сохранен как wchar_t, Но это не обязательно подразумевает Unicode. Например, вы можете использовать строку широких символов для кодирования GB 18030, набора символов, используемого в Китае, который похож на Unicode. Стандарт C++03 не имеет ничего общего с Unicode (однако C++11 определяет типы символов Unicode и строковые литералы), поэтому вы должны правильно представлять строки Unicode в C++03.

Что касается строковых литералов, в главе 2 (Лексические соглашения) стандарта C++ упоминается "базовый исходный набор символов", который в основном эквивалентен ASCII. Так что это, по сути, гарантирует, что "abc" будет представлен в виде 3-байтовой строки (не считая нуля), и L"abc" будет представлен в виде 3 * sizeof(wchar_t)-байтовая строка широких символов.

Стандарт также упоминает "универсальные имена символов", которые позволяют вам ссылаться на символы не ASCII, используя \uXXXX шестнадцатеричное обозначение. Эти "универсальные имена символов" обычно отображаются непосредственно в значения Unicode, но стандарт не гарантирует, что они должны. Однако вы можете, по крайней мере, гарантировать, что ваша строка будет представлена ​​в виде определенной последовательности байтов, используя универсальные имена символов. Это гарантирует вывод Unicode, если среда выполнения поддерживает Unicode, установлены соответствующие шрифты и т. Д.

Что касается строковых литералов в исходных файлах C++03, опять же нет никаких гарантий. Если в вашем коде есть строковый литерал Unicode, который содержит символы за пределами диапазона ASCII, ваш компилятор должен решить, как интерпретировать эти символы. Если вы хотите явно гарантировать, что компилятор будет "делать правильные вещи", вам нужно будет использовать \uXXXX запись в ваших строковых литералах.

В C++03 не упоминается Unicode (в будущем C++0x). В настоящее время вы должны либо использовать внешние библиотеки ( ICU, UTF-CPP и т. Д.), Либо создать собственное решение с использованием кода для конкретной платформы. Как уже упоминалось, кодировка wchar_t (или даже размер) не указана. Следовательно, строковое литеральное кодирование зависит от конкретной реализации. Однако вы можете задать кодовые точки Юникода в строковых литералах, используя escape-символы \x \u \U.

Обычно приложения Unicode в Windows используют wchar_t (с кодировкой UTF-16) в качестве внутреннего символьного формата, потому что это облегчает использование API-интерфейсов Windows, так как сама Windows использует UTF-16. Unic / Unix-приложения Unix/Linux, в свою очередь, обычно используют char (с кодировкой UTF-8) внутри. Если вы хотите обмениваться данными между различными платформами, UTF-8 является обычным выбором для кодирования передачи данных.

Стандарт не упоминает форматы кодирования строк.

Взгляните на ICU от IBM (это бесплатно). http://site.icu-project.org/

Другие вопросы по тегам