\??
- это каталог виртуальных объектов ядра, в котором диспетчер объектов ищет локальные и глобальные символические ссылки устройства DOS. Сначала он проверяет локальные ссылки на устройства DOS для сеанса входа пользователя в \Sessions\0\DosDevices\[Logon_AuthenticationId]
. Затем он проверяет ссылки на глобальные устройства DOS в \Global??
. Еще в старые времена NT использовал один каталог \DosDevices
. В настоящее время \DosDevices
является ссылкой на \??
. Кроме того, в каждом локальном каталоге устройств DOS есть ссылка «Глобальная», чтобы разрешить доступ к глобальным устройствам, когда локальное устройство затеняет глобальное (например, \\?\Global\Z:
) или разрешить драйверу устройства создавать глобальное устройство, если оно не выполняется в системе нить.
В пользовательском режиме библиотека времени выполнения в файле ntdll.dll преобразует полностью определенный путь DOS / Windows к пути NT путем добавления \??\
для буквы диска или замены ведущего \\
Путь UNC с \??\UNC\
- за исключением путей \\?\
и \\.\
локального устройства просто заменяется на \??\
. Но сначала путь устройства \\.\
претерпевает некоторую предварительную обработку, например, разрешение «.». и "..", тогда как \\?\
обходит все предварительную обработку пользовательского режима.
Например, обычно \\?\C:\Windows
преобразуется в \??\C:\Windows
, который разрешает \Global??\C:\Windows
. Устройство DOS с буквой «C:» является символической ссылкой на устройство громкости NT. Конечная цель зависит от системы. Например, конечный путь NT может разрешить \Device\HarddiskVolume2\Windows
.
Соединения устройств DOS, такие как Volume{00000000-0000-0000-0000-000000000000}
, создаются диспетчером точки монтирования. Это клей между постоянными буквами дисков, точками монтирования NTFS и используемым в данный момент устройством тома NT, например \Device\HarddiskVolume2
.
Обратите внимание, что это не о "строгом unicode, программирующем" по сути, но некотором практическом опыте.
то, Что мы сделали в моей компании, должно было создать библиотеку-оболочку вокруг библиотеки ICU IBM. Библиотека-оболочка имеет интерфейс UTF-8 и преобразовывает в UTF-16, когда необходимо назвать ICU. В нашем случае мы не волновались слишком много о хитах производительности. Когда производительность была проблемой, мы также предоставили интерфейсы UTF-16 (использующий наш собственный тип данных).
Приложения могли остаться в основном как есть (использующий символ), хотя в некоторых случаях они должны знать об определенных вопросах. Например, вместо strncpy () мы используем обертку, которая старается не отключать последовательности UTF-8. В нашем случае это достаточно, но можно было также рассмотреть проверки на комбинированные символы. У нас также есть обертки для подсчета количества кодовых точек, количества графем, и т.д.
При взаимодействии через интерфейс с другими системами, мы иногда должны делать пользовательский символьный состав, таким образом, Вам, возможно, понадобится некоторая гибкость там (в зависимости от Вашего приложения).
Мы не используем wchar_t. Используя ICU избегает неожиданных проблем в мобильности (но не другие неожиданные проблемы, конечно, :-).
Этот FAQ является богатством информации Между той страницей и эта статья Joel Spolsky , у Вас будет хорошее начало.
Одно заключение я приехал в по пути:
wchar_t
16 битов в Windows, но не обязательно 16 битов на других платформах. Я думаю, что это - необходимое зло в Windows, но вероятно может избежаться в другом месте. Причина это важно в Windows, состоит в том, что Вам нужен он для использования файлов, которые имеют символы неASCII на имя (наряду с версией W функций).
Примечание, что Windows APIs, которые берут wchar_t
строки, ожидает кодировку UTF-16. Обратите внимание также, что это отличается, чем UCS-2. Примите во внимание суррогатные пары. Этот тестовая страница имеет поучительные тесты.
, Если Вы программируете в Windows, Вы не можете использовать fopen()
, fread()
, fwrite()
, и т.д. так как они только берут char *
и не понимают кодировки UTF-8. Делает мобильность болезненной.
Сделать строгое программирование Unicode:
strlen
, strcpy
... но их widestring дубликаты wstrlen
, wsstrcpy
...) Многобайтовый символ, упорядочивают, кодирование, которое предшествует кодировке UTF-16 (тот, используемый обычно с wchar_t
), и это кажется мне, это довольно только для Windows.
я никогда не слышал о wint_t
.
Вы в основном хотите иметь дело со строками в памяти как wchar_t массивы вместо символа. Когда Вы делаете любой вид ввода-вывода (как чтение/запись файлов), можно кодировать/декодировать использование UTF-8 (это - вероятно, наиболее распространенное кодирование), который достаточно прост реализовать. Просто погуглите RFCs. Таким образом в оперативной памяти ничто не должно быть многобайтовым. Один wchar_t представляет один символ. Когда Вы приходите к сериализации однако, именно тогда необходимо закодировать к чему-то как UTF-8, где некоторые символы представлены несколькими байтами.
необходимо будет также записать новые версии strcmp и т.д. для строк широкого символа, но это не большая проблема. Самой большой проблемой будет interop с кодом библиотек / существующим кодом, которые только принимают массивы символов.
И когда дело доходит до sizeof (wchar_t) (Вам будут нужны 4 байта, если Вы захотите сделать его правильно) можно всегда переопределять его к большему размеру со взломами определения типа/макроса, если Вы должны.
стандарт C (C99) предусматривает широкие символы и многобайтовые символы, но так как нет никакой гарантии о том, что могут содержать те широкие символы, их значение несколько ограничено. Для данной реализации они оказывают полезную поддержку, но если Ваш код должен смочь переместиться между реализациями, существует недостаточная гарантия, что они будут полезны.
, Следовательно, подход, предложенный Hans van Eck (который должен записать обертку вокруг ICU - Международных Компонентов для Unicode - библиотека), является звуковым, IMO.
кодировка UTF-8 имеет много достоинств, одно из которых - то, что, если Вы не смешиваете с данными (путем усечения ее, например), затем она может быть скопирована функциями, которые не полностью осведомлены о запутанности кодировки UTF-8. Это - категорически не случай с wchar_t
.
Unicode полностью является 21-разрядным форматом. Таким образом, Unicode резервирует кодовые точки от U+0000 до U+10FFFF.
Одна из полезных вещей о UTF-8, UTF-16 и форматы UTF-32 (где UTF обозначает Формат преобразования Unicode - видят Unicode) - то, что можно преобразовать между этими тремя представлениями без потери информации. Каждый может представить что-либо, что другие могут представить. И UTF-8 и UTF-16 являются многобайтовыми форматами.
UTF-8 известен быть многобайтовым форматом с осторожной структурой, которая позволяет найти запуск символов в строке надежно, запускающийся в любой точке в строке. Однобайтовые символы имеют высоко-разрядный набор для обнуления. Многобайтовые символы имеют первый символ, запускающийся с одной из комбинаций двоичных разрядов 110, 1110 или 11110 (для 2 байтов, 3-байтовых или 4-байтовых символов), с последующими байтами, всегда запускающимися 10. Символы продолжения всегда находятся в диапазоне 0x80.. 0xBF. Существуют правила, что символы UTF-8 должны быть представлены в минимальном возможном формате. Одно последствие этих правил то, что байты 0xC0 и 0xC1 (также 0xF5.. 0xFF), не может появиться в допустимых данных UTF-8.
U+0000 .. U+007F 1 byte 0xxx xxxx
U+0080 .. U+07FF 2 bytes 110x xxxx 10xx xxxx
U+0800 .. U+FFFF 3 bytes 1110 xxxx 10xx xxxx 10xx xxxx
U+10000 .. U+10FFFF 4 bytes 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx
Первоначально, надеялись, что Unicode будет набором 16-битного кода, и все вписалось бы в пространство 16-битного кода. К сожалению, реальный мир более сложен, и он должен был быть расширен до текущего 21-разрядного кодирования.
UTF-16 таким образом является единым блоком (16-разрядное слово) кодовый набор для 'Основной Многоязычной Плоскости', означая символы с кодовыми точками Unicode U+0000.. U+FFFF, но использование две единицы (32 бита) для символов вне этого диапазона. Таким образом код, который работает с кодировкой UTF-16, должен смочь обработать кодировку переменной ширины, точно так же, как UTF-8 должен. Коды для символов двойной единицы называют суррогатами.
Суррогаты являются кодовыми точками от двух специальных диапазонов значений Unicode, зарезервированных для использования в качестве продвижения и запаздывающих значений парных элементов кода в UTF-16. Продвижение, также названный высоко, суррогаты от U+D800 до U+DBFF и запаздывания, или низко, суррогаты от U+DC00 до U+DFFF. Их называют суррогатами, так как они не представляют символы непосредственно, но только как пара.
UTF-32, конечно, может закодировать любую кодовую точку Unicode в едином блоке устройства хранения данных. Это эффективно для вычисления, но не для устройства хранения данных.
можно найти намного больше информации в веб-сайты Unicode и ICU.
<uchar.h>
стандарт C11 изменил правила, но не все реализации догнали изменения даже сейчас (середина 2017). Стандарт C11 суммирует изменения для поддержки Unicode как:
- символы Unicode и строки (
<uchar.h>
) (первоначально указанный в ISO/IEC TR 19769:2004)
, Что следует, являются пустой минимальной схемой функциональности. Спецификация включает:
6.4.3 Универсальных имен персонажей
Синтаксис
универсальное имя персонажа:
\u
шестнадцатеричная четверка
\U
шестнадцатерично-квадратическая шестнадцатеричная четверка
шестнадцатеричная четверка:
шестнадцатерично-разрядный шестнадцатерично-разрядный шестнадцатерично-разрядный шестнадцатерично-разрядный7.28 утилит Unicode
<uchar.h>
заголовок
<uchar.h>
объявляет типы и функции для управления символами Unicode.объявленные типы
mbstate_t
(описаны в 7.29.1) иsize_t
(описанный в 7,19);char16_t
, который является типом беззнаковых целых чисел, используемым для 16-разрядных символов, и является тем же типом как [1 112] (описанный в 7.20.1.2); и
char32_t
, который является типом беззнаковых целых чисел, используемым для 32-разрядных символов, и является тем же типом как [1 113] (также описанный в 7.20.1.2).
(Перевод перекрестных ссылок: <stddef.h>
определяет size_t
, <wchar.h>
определяет mbstate_t
, и <stdint.h>
определяет uint_least16_t
и uint_least32_t
.) <uchar.h>
заголовок также определяет минимальный набор (прерываемых) функций преобразования:
mbrtoc16()
c16rtomb()
mbrtoc32()
c32rtomb()
существуют правила, о которых символы Unicode могут использоваться в идентификаторах с помощью \unnnn
или \U00nnnnnn
нотации. Вам, вероятно, придется активно активировать поддержку таких символов в идентификаторах. Например, GCC требует -fextended-identifiers
позволять их в идентификаторах.
Примечание, которое macOS Горная цепь (10.12.5), для именования, но одна платформа, не поддерживает <uchar.h>
.
Из того, что я знаю, wchar_t является зависящим от реализации (как видно из этого статья Wiki). И это не unicode.
strtotime()
, если у Вас есть возможность использовать DateTime
объект. + strtotime()
не всегда соответствует, и это знало проблемы, но ответ будет определенно работать на большинство случаев.
– Paul T. Rawkeen
28 July 2012 в 21:24
Самое важное - всегда четко различать текстовые и двоичные данные . Попробуйте следовать модели Python 3.x str
против байтов
или SQL ТЕКСТ
против BLOB
.
К сожалению, C сбивает с толку, используя char
как для «символа ASCII», так и для int_least8_t
. Вы захотите сделать что-то вроде:
typedef char UTF8; // for code units of UTF-8 strings
typedef unsigned char BYTE; // for binary data
Вам могут понадобиться typedef для кодовых единиц UTF-16 и UTF-32, но это более сложно, потому что кодировка wchar_t
не определена. Вам понадобится только препроцессор #if
s. Вот некоторые полезные макросы в C и C ++ 0x:
__ STDC_UTF_16 __
- Если определено, тип _Char16_t
существует и является UTF-16. __ STDC_UTF_32 __
- Если определено, тип _Char32_t
существует и является UTF-32. __ STDC_ISO_10646 __
- Если определено, то wchar_t
будет UTF-32. _WIN32
- В Windows wchar_t
является UTF-16, хотя это нарушает стандарт. WCHAR_MAX
- Может использоваться для определения размера wchar_t
, но не для определения того, использует ли ОС его для представления Unicode. Означает ли это, что мой код должен нигде не используйте типы символов, и что необходимо использовать функции, которые могут иметь дело с wint_t и wchar_t?
См. также:
Нет.UTF-8 - это совершенно допустимая кодировка Unicode, в которой используются строки char *
. Его преимущество заключается в том, что если ваша программа прозрачна для байтов, отличных от ASCII (например, конвертер окончания строки, который действует на \ r
и \ n
, но пропускает другие символы без изменений), вам вообще не нужно вносить никаких изменений!
Если вы используете UTF-8, вам нужно будет изменить все предположения, что char
= символ (например, не вызывайте toupper
в цикле) или char
= столбец экрана (например, для переноса текста).
Если вы выберете UTF-32, у вас будет простота символов фиксированной ширины (но не графем фиксированной ширины , но вам нужно будет изменить тип всех ваших строк).
Если вы выберете UTF-16, вам придется отказаться как от предположения о символах фиксированной ширины , так и от предположения о 8-битных единицах кода, что делает этот путь обновления наиболее трудным. однобайтовые кодировки.
Я бы рекомендовал активно избегать wchar_t
, потому что он не кроссплатформенный: иногда это UTF-32, иногда UTF-16, а иногда это восточноазиатская кодировка до Unicode. Я бы рекомендовал использовать typedef
Что еще более важно, избегайте TCHAR
.