Является ли широкий литерал буква символов, начинающийся с L, как L "Hello World", гарантированный для кодирования в Unicode?
Недавно я попытался получить полное представление о том, какие шаги требуется для создания независимых на платформе приложений на С++, поддерживающих unicode. Меня смущает то, что большинство howtos и прочее выравнивают кодировку символов (то есть ANSI или Unicode) и тип символа (char или wchar_t). Как я уже узнал, это разные вещи, и может существовать последовательность символов, закодированная в Юникоде, но представленная std::string, а также последовательность символов, закодированная в ANSI, но представленная как std:: wstring, правильно?
Итак, вопрос, который приходит мне на ум, заключается в том, дает ли стандарт С++ какую-либо гарантию относительно кодирования строковых литералов, начиная с L
, или просто говорит это типа wchar_t со специфической кодировкой для конкретной версии?
Если такой гарантии нет, означает ли это, что мне нужна какая-то внешняя система ресурсов для предоставления строковых литералов без ASCII для моего приложения независимо от платформы?
Каков предпочтительный способ для этого? Система ресурсов или правильное кодирование исходных файлов плюс правильные параметры компилятора?
Ответы
Ответ 1
Символ L
перед строковым литералом просто означает, что каждый символ в строке будет сохранен как wchar_t
. Но это не обязательно означает Unicode. Например, вы можете использовать широкую строку символов для кодирования GB 18030, набор символов, используемый в Китае, который похож на Unicode. Стандарту С++ 03 нечего сказать о Unicode (однако С++ 11 определяет Unicode char типы и строковые литералы), поэтому вам нужно правильно представлять строки Unicode в С++ 03.
Что касается строковых литералов, в главе 2 (Лексические условные обозначения) стандарта С++ упоминается "базовый набор символов источника", который в основном эквивалентен ASCII. Таким образом, это по существу гарантирует, что "abc"
будет отображаться как 3-байтовая строка (не считая нуля), а L"abc"
будет представлена как строка 3 * sizeof(wchar_t)
-байта широких символов.
В стандарте также упоминаются "универсальные имена символов", которые позволяют ссылаться на символы, отличные от ASCII, с использованием шестнадцатеричной нотации \uXXXX
. Эти "универсальные имена" обычно отображаются непосредственно в значениях Unicode, но стандарт не гарантирует, что они должны. Тем не менее, вы можете по крайней мере гарантировать, что ваша строка будет представлена как определенная последовательность байтов, используя имена универсальных символов. Это гарантирует выход Unicode, если среда выполнения поддерживает Unicode, имеет соответствующие шрифты и т.д.
Что касается строковых литералов в исходных файлах С++ 03, то опять нет гарантии. Если у вас есть строковый литерал Unicode в коде, который содержит символы вне диапазона ASCII, то ваш компилятор должен решить, как интерпретировать эти символы. Если вы хотите явно гарантировать, что компилятор "пойдет правильно", вам нужно будет использовать обозначение \uXXXX
в ваших строковых литералах.
Ответ 2
В стандарте не упоминаются форматы кодирования для строк.
Взгляните на ICU от IBM (бесплатно). http://site.icu-project.org/
Ответ 3
С++ 03 не упоминает unicode (будущий С++ 0x делает). В настоящее время вам нужно либо использовать внешние библиотеки (ICU, UTF -CPP и т.д.) Или создать собственное решение с использованием кода платформы. Как отмечали другие, кодировка wchar_t (или даже размер) не указана. Следовательно, строковое литераловое кодирование является специфичным для реализации. Тем не менее, вы можете указывать коды в кодировке unicode в строковых литералах с помощью \x\u\U экранов.
Обычно приложения Unicode в Windows используют wchar_t (с кодировкой UTF-16) в качестве внутреннего символьного формата, поскольку он упрощает использование Windows API, поскольку сама ОС использует UTF-16. Unic/Linux unicode-приложения, в свою очередь, обычно используют char (с кодировкой UTF-8) внутри. Если вы хотите обмениваться данными между различными платформами, UTF-8 является обычным выбором для кодирования передачи данных.