Перейти к содержимому

Как использовать юникод в c

  • автор:

Поддержка Юникода

Юникод — это спецификация для поддержки всех наборов символов, включая те, которые не могут быть представлены в одном байте. Если вы программуете для международного рынка, рекомендуется использовать Юникод или многобайтовый набор символов (МБ CS). Или кодируйте программу, чтобы ее можно было создать, изменив переключатель.

Расширенный символ — это двухбайтовый многоязыковой код символа. Десятки тысяч символов, составляющих почти все символы, используемые в современных вычислениях во всем мире, включая технические символы и специальные символы публикации, можно представить в соответствии со спецификацией Юникода как один широкий символ, закодированный с помощью UTF-16. Символы, которые не могут быть представлены только в одном широком символе, можно представить в паре Юникода с помощью функции суррогатной пары Юникода. Так как почти каждый символ в общем использовании представлен в UTF-16 в одном 16-разрядном широком символе, используя широкие символы, упрощает программирование с помощью международных наборов символов. Широкие символы, закодированные с помощью UTF-16LE (для маленького эндиана) — это собственный формат символов для Windows.

Строка расширенных символов представляется как массив wchar_t[] , и на нее указывает указатель wchar_t* . Любой символ ASCII может быть представлен как расширенный символ путем добавления к нему префикса «L». Например, «L’\0′» является 16-битным расширенным символом для значения NULL. Подобным образом все строковые литералы, составленные из символов ASCII, могут быть представлены как строковые литералы из расширенных символов путем добавления к литералу ASCII префикса «L» (L»Hello»).

Как правило, расширенные символы занимают больше памяти, чем многобайтовые символы, однако они обрабатываются быстрее. Кроме того, в многобайтовой кодировке может представляться только один языковой стандарт, а все наборы символов в мире представлены одновременно представлением Юникода.

Поддержка Юникода обеспечивается для всех компонентов платформы MFC. MFC обеспечивает поддержку Юникода с помощью переносимых макросов, как показано в следующей таблице.

Типы переносимых данных в MFC

Непереносимый тип данных Макрос, которым он заменяется
char , wchar_t _TCHAR
char* , LPSTR (тип данных Win32), LPWSTR LPTSTR
const char* , LPCSTR (тип данных Win32), LPCWSTR LPCTSTR

Класс CString используется _TCHAR в качестве основы и предоставляет конструкторы и операторы для простых преобразований. Большинство операций со строками Юникода может быть написано с помощью средств, которые используются для обработки кодировки Windows ANSI. Единственным отличием является то, что основной единицей операции является шестнадцатибитный символ, а не восьмибитный. В отличие от многобайтовых кодировок нет необходимости (и не следует) обрабатывать символы Юникода как два отдельных байта. Однако необходимо иметь дело с возможностью одного символа, представленного суррогатной парой широких символов. Как правило, не писать код, предполагающий длину строки, совпадает с числом символов, будь то узкие или широкие, содержащиеся в нем.

Что вы хотите сделать?

  • Использование поддержки юникода mFC и многобайтового набора символов (МБ CS)
  • Включение Юникода в моей программе
  • Включение Юникода и МБ CS в моей программе
  • Создание интернационализированной программы с помощью Юникода
  • Узнайте о преимуществах Юникода
  • Используйте wmain, чтобы я смог передать аргументы с широкими символами в мою программу
  • См. сводку по программированию Юникода
  • Сведения о сопоставлениях универсального текста для переносимости байтовой ширины

Поддержка Юникода и многобайтовой кодировки

Некоторые языки, например японский и китайский, имеют большие наборы символов. Для поддержки программирования на этих рынках библиотека классов Microsoft Foundation (MFC) позволяет использовать два различных подхода к обработке больших наборов символов:

  • Юникод, основанные на расширенных символах и строках, wchar_t закодированных как UTF-16.
  • Многобайтовые символьные наборы (МБ CS)char на основе однобайтовых или двойных байтовых символов и строк, закодированных в наборе символов для языкового стандарта.

Корпорация Майкрософт рекомендовала библиотеки Юникода MFC для всех новых разработок, а библиотеки МБ CS были устарели в Visual Studio 2013 и Visual Studio 2015. Это больше не требуется. Предупреждения об отмене МБ CS были удалены в Visual Studio 2017.

Поддержка MFC строк Юникода

Вся библиотека классов MFC условно включена для символов и строк Юникода, хранящихся в широких символах в виде UTF-16. В частности, класс CString включен в Юникоде.

Эти библиотеки, отладчик и DLL-файлы используются для поддержки Юникода в MFC:

U.LIB версииMFC
UD версииMFC. LIB
MFCMверсииU.LIB
UD версииMFCM. LIB
MFCSверсииU.LIB
UD версииMFCS. LIB
UAFXCW. LIB
UAFXCWD. LIB

MFCверсииU.PDB
UD версииMFC. PDB
MFCMверсииU.PDB
UD версииMFCM. PDB
MFCSверсииU.PDB
UD версииMFCS. PDB
UAFXCW. PDB
UAFXCWD. PDB

U.DLL версииMFC
MFCверсииUD.DLL
U.DLL версииMFCM
MFCMверсииUD.DLL

(версия представляет номер версии файла. Например, «140» означает версию 14.0.)

CString основан на типе TCHAR данных. Если символ _UNICODE определен для сборки программы, TCHAR определяется как тип wchar_t , 16-разрядный тип кодировки символов. TCHAR В противном случае определяется как char обычная 8-разрядная кодировка символов. Таким образом, CString в Юникоде используется 16-разрядный символ. Без Юникода он состоит из символов типа char .

Чтобы завершить программирование в Юникоде приложения, необходимо также:

  • _T Используйте макрос для условного кода строк литералов, которые будут переноситься в Юникод.
  • При передаче строк обратите внимание на то, требуются ли аргументы функции длину символов или длину в байтах. Разница важна, если вы используете строки Юникода.
  • Используйте переносимые версии функций обработки строк во время выполнения C.
  • Используйте следующие типы данных для символов и указателей символов:
    • Используйте место, где вы будете TCHAR использовать char .
    • Используйте место, где вы будете LPTSTR использовать char*.
    • Используйте место, где вы будете LPCTSTR использовать const char*. CString предоставляет оператор LPCTSTR для преобразования между CString и LPCTSTR .

    CString также предоставляет конструкторы с поддержкой Юникода, операторы назначения и операторы сравнения.

    Справочник по библиотеке времени выполнения определяет переносимые версии всех функций обработки строк. Дополнительные сведения см. в разделе «Интернационализация категорий».

    Поддержка MFC для строк МБ CS

    Библиотека классов также включена для многобайтовых наборов символов, но только для двухбайтовых наборов символов (DBCS).

    В многобайтовом наборе символов символ может быть одним или двумя байтами. Если это два байта, его первый байт является специальным «байтом свинца», выбранным из определенного диапазона, в зависимости от используемой кодовой страницы. В совокупности свинца и «байты тропы» указывают уникальную кодировку символов.

    Если символ _MBCS определен для сборки программы, введите TCHAR тип, на основе которого CString используется, сопоставляется char с . Вы можете определить, какие байты в CString байтах являются потенциальными и которые являются конечными байтами. Библиотека времени выполнения C предоставляет функции, помогающие определить это.

    В DBCS указанная строка может содержать все однобайтовые символы ANSI, все двубайтовые символы или комбинацию двухбайтовых символов. Для этих возможностей требуется особое внимание при анализе строк. К ним относятся CString объекты.

    Сериализация строк Юникода в MFC может считывать строки Юникода и МБ CS независимо от версии запущенного приложения. Файлы данных переносятся между Юникодом и МБ CS версий программы.

    CString Функции-члены используют специальные версии функций времени выполнения C или используют функции с поддержкой Юникода. Таким образом, например, если CString функция обычно вызывается strcmp , она вызывает соответствующую функцию _tcscmp универсального текста. В зависимости от того, как определены символы _MBCS и _UNICODE определены, _tcscmp сопоставляется следующим образом:

    Символы Функция
    _MBCS Определенные _mbscmp
    _UNICODE Определенные wcscmp
    Ни определенный символ strcmp

    Символы _MBCS и _UNICODE являются взаимоисключающими.

    Сопоставления универсальных текстовых функций для всех подпрограмм обработки строк во время выполнения рассматриваются в справочнике по библиотеке времени выполнения C. Список см. в разделе «Интернационализация».

    Аналогичным образом CString методы реализуются с помощью универсальных сопоставлений типов данных. Чтобы включить как МБ CS, так и Юникод, MFC используется TCHAR для char или ( LPTSTR char * или wchar_t wchar_t* ) и LPCTSTR для const char * или . const wchar_t* Они обеспечивают правильные сопоставления для МБ CS или Юникода.

    Как использовать юникод в c

    Для поддержки строк с символами кодировок Unicode в С++ в модуле также есть еще ряд дополнительных типов строк.

    • std::wstring содержит строку символов типа wchar_t
    • std::u8string содержит строку символов типа char8_t (добавлена в C++20)
    • std::u16string содержит строку символов типа char16_t
    • std::u32string содержит строку символов типа char32_t

    Например, определим переменную типа std::wstring

    std::wstring text;

    Ее также можно инициализировать конкретной строкой. При присвоении переменной wstring перед строкой указывается префикс L . Для определения строк других типов также применяются определенные суффиксы: u8 для u8string, u для u16string и U для u32string. Например, определим переменные этих типов

    std::wstring text ; std::u8string text8; std::u16string text16 ; std::u32string text32 ;

    Для вывода строки типа std::wstring применяется поток std::wcout

    #include #include int main() < std::wstring text ; std::wcout 

    Для вывода строк остальных типов в С++ пока не определено своих типов потоков.

    В остальном работа со строками этих типов аналогична работе с типом string , они могут использовать те же функции, что и тип string .

    Однако стоит учитывать, что поскольку wstring использует тип символов wchar_t , то кодировка символов таких строк зависит от компилятом. На Windows обычно применяется UTF-16, соответственно строка будет состоять из 2-байтовых символов UTF-16. Но в большинстве других систем применяются 4-байтные символы UTF-32 wchar_t . На этом фоне типы u8string , u16string и u32string выглядят более предпочтительно, однако на данный момент в C++ имеется довольно ограниченная поддержка по работе с символами Unicode.

    Как использовать юникод в консоли windows с wstring?

    60cc7bfa737da157285127.png

    Т.е. первые два варианта отрабатывают нормально, но в случае ввода в консоль получаются неизвестные символы.

    Как это можно исправить?
    Так же как можно решить проблему с тем, что программа принимает аргументы командной строки, которая по умолчанию в 866 и символы в любом случае будут приходить в этой кодировке и сменой кодировки во время выполнения проблему не решить?

    • Вопрос задан более двух лет назад
    • 625 просмотров

    Комментировать
    Решения вопроса 1
    Developer, ex-admin

    Аргументы командной строки не обязательно будут в 866 кодировке, могут быть и в 1251 - зависит от кодировки консоли, которую можно менять консольной командой chcp.
    Вообще не стоит использовать юникод в консоли, т.к. виндовая консоль не слишком дружит с юникодом.
    Например, если захотите обработать вывод вашей программы каким-нибудь фильтром в батнике, то при юникоде могут быть проблеммы.
    Хотя внутри программы вы можете использовать юникод, но в этом случае вы должны будете перекодировать весь ввод и вывод. Не уверен, можно ли настроить стандартную библиотеку, чтобы она сама занималась перекодировкой.
    А так в WinAPI есть целый набор консольных функций, в т.ч. можно получить текущую кодировку консоли для ввода и вывода, установить нужную кодировку, перекодировать текст.

    Ответ написан более двух лет назад
    Mars36 @Mars36 Автор вопроса

    Юникод используется в конкретном случае при вводе в консоль. В другом случае я бы с ним не заморачивался. В начале мейна я пробовал использовать SetConsoleCP, SetConsoleOutputCP, selLocal. Но результата это не дало, найти другие мне не удалось. Не можете подсказать какие конкретно функции должны быть для этого?

    Mars36, Юникод бывает разный: UTF8, UTF16, UTF32 и это только наиболее распространенные варианты и то есть еще и "подвиды". Какой конкретно юникод у вас подается на вход?

    Я подозреваю юникод у вас подается в программу из файла с помощью перенаправления stdin.
    Тогда можно при вводе в принципе не привязываться к кодировке консоли. Кодировка важна, только когда вы что-то выводите на экран (чтоб правильно отображались символы) или когда начинаете сравнивать 2 строки (они должны быть в одной кодировке).
    Вы можете просто прочитать входную строку. При этом не важно какая кодировка консоли будет - прочитается ровно то что будет подано на вход. Вы же читаете не сами символы, а коды символов, коды будут те что были поданы на вход. Кодировка это лишь интерпретация кодов.
    Входная кодировка у вас известна. Можно просто применить функцию перекодировки (или парную ей) в требуемую вам кодировку.
    В качестве входной кодировки указывайте не ту, что установлена в консоли, а ту что вам известна априори.
    Или вы можете внутри программы использовать ту же кодировку, которую ждете на входе. Тогда можно вход не перекодировать.
    Выходные сообщения и параметры командной строки потребуется перекодировать, если внутренняя кодировка отличается от кодировки консоли.

    Но если входные условия изменятся, например входной файл будет закодирован в другой кодировке, или вместо файла придется читать консольный ввод, то придется модифицировать код. Что бы этого избежать есть смысл в параметрах задавать входную кодировку.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *