Да, кодировка UTF-8 может использоваться с символами char, string и stringstream. Символ будет содержать единый кодовый блок UTF-8, из которых может потребоваться до четырех символов для представления одной кодовой точки Юникода.
Однако есть несколько проблем с использованием UTF-8 специально с компиляторами Microsoft. В реализациях C++ используется «набор символов выполнения» для ряда вещей, таких как кодирующий символ и строковые литералы. VC++ всегда использует кодировку языкового стандарта системы как набор символов выполнения, а Windows не поддерживает UTF-8 в качестве кодировки локали системы, поэтому UTF-8 никогда не может использоваться набором символов выполнения.
Это означает, что VC++ никогда не преднамеренно создает символы UTF-8 и строковые литералы. Вместо этого компилятор должен быть обманут.
Компилятор преобразует из известной кодировки исходного кода в исполняемую кодировку. Это означает, что если компилятор использует кодировку locale для кодировки источника и исполнения, преобразование не выполняется.Если вы можете получить данные UTF-8 в исходный код, но компилятор считает, что источник использует кодировку локали, тогда символьные и строковые литералы будут использовать кодировку UTF-8. VC++ использует так называемую «спецификацию» для обнаружения исходной кодировки и использует кодировку locale, если BOM не обнаружена. Поэтому вы можете получить кодированные строковые литералы UTF-8, сохранив все ваши исходные файлы как «UTF-8 без подписи».
Есть предостережения с этим методом. Во-первых, вы не можете использовать UCN с узкими символами и строковыми литералами. Универсальные имена символов должны быть преобразованы в набор символов выполнения, который не является UTF-8. Вы должны либо написать символ буквально, чтобы он отображался как UTF-8 в исходном коде, либо вы можете использовать шестнадцатеричные экраны, где вы вручную выписываете кодировку UTF-8. Во-вторых, для получения широких символов и строковых литералов компилятор выполняет аналогичное преобразование из исходной кодировки в широкий набор символов выполнения (который всегда является UTF-16 в VC++). Поскольку мы лжем компилятору о кодировке, он будет неправильно выполнять это преобразование в UTF-16. Таким образом, в широких символах и строковых литералах вы не можете использовать символы не-ascii буквально, и вместо этого вы должны использовать UCN или шестнадцатеричные escape-последовательности.
UTF-8 - это переменная длина (как и UTF-16). Индексы, используемые с at()
и substr()
, составляют единиц кода, а не индексы символов или кодовых точек. Поэтому, если вы хотите использовать конкретный блок кода, вы можете просто индексировать строку или массив или как обычно. Если вам нужна конкретная точка кода, вам понадобится библиотека, которая может понять, как составлять кодовые единицы UTF-8 в кодовые точки (например, Boost Unicode iterators library), или вам нужно преобразовать данные UTF-8 в UTF-32. Если вам нужны фактические воспринимаемые пользователем символы, вам нужна библиотека, которая понимает, как кодовые точки составлены в символы. Я полагаю, что ICU имеет такую функциональность, или вы можете реализовать Default Grapheme Cluster Boundary Specification по стандарту Unicode.
Приведенное выше рассмотрение UTF-8 действительно имеет значение для того, как вы записываете данные Unicode в исходный код. Он мало влияет на ввод и вывод программы.
Если ваши требования позволяют вам выбрать способ ввода и вывода, я бы порекомендовал использовать UTF-8 для ввода. В зависимости от того, что вам нужно сделать с помощью ввода, вы можете либо преобразовать его в другую кодировку, которую легко обрабатывать, либо написать свои процедуры обработки для работы непосредственно на UTF-8.
Если вы хотите когда-либо выводить что-либо через консоль Windows, тогда вам нужен четко определенный модуль для вывода, который может иметь разные реализации, потому что для интернационализированного вывода на консоль Windows потребуется другая реализация либо из вывода в файл на Windows или консоли и вывод файлов на другие платформы. (На других платформах консоль - это еще один файл, но консоль Windows нуждается в специальной обработке.)
Для UTF wchar_t рекомендуется хранить. Вы можете хранить UTF-8 в символе без проблем, но результаты будут странными. – perilbrain
@ Анонимный, который зависит от вашей платформы (и от *, который * аромат UTF вам интересен). В Windows 'wchar_t' подходит для UTF-16. В Linux целесообразно использовать для UTF-32. Для UTF-8 'char' является довольно разумным кандидатом (если у вас нет доступа к« новым »типам символов в C++ 11) – jalf
Эта программа будет перенесена на разные платформы. Какой тип символа можно использовать лучше всего для этой цели? – Qman