Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.129.70.157] |
|
Сообщ.
#1
,
|
|
|
Здравствуйте!
Я кажется забыл номера кодировок. Странно. В таблице написано что utf-16 это 1200 и 1201. Но не работает! https://msdn.microsoft.com/en-us/library/wi...ror=-2147217396 Некоторые функции, начали отказыватся принимать номера кодировок. Делаю маленькую тулзу. Обычный MultiByteToWideChar и всё такое. И вдруг, когда стал указывать ей utf-16 le, utf-16 be, она выдала ошибку. Я удивился, но в итоге, сделал простенькую проверку. /* это работает. */ _ASSERTE( ::IsValidCodePage( 65001 ) ); /* это ругается. */ _ASSERTE( ::IsValidCodePage( 1200 ) ); _ASSERTE( ::IsValidCodePage( 1201 ) ); _ASSERTE( ::IsValidCodePage( 12000 ) ); _ASSERTE( ::IsValidCodePage( 12001 ) ); Не пойму, в чём я накосячил? Раньше нечто подобное писал, но такого не проявлялось. Может быть, в самом деле, напутал с кодировками? А есть ли константы аналогичные CP_UTF8 для других юникодовых страниц? |
Сообщ.
#2
,
|
|
|
Цитата Eric-S @ И вдруг, когда стал указывать ей utf-16 le, utf-16 be, она выдала ошибку. А какую, если не секрет? |
Сообщ.
#3
,
|
|
|
Цитата B.V. @ GetLastError возвращает 0 - всё хорошо. А те функции просто говорят, что "страницы неверные":А какую, если не секрет? Цитата справка Return Value Returns a nonzero value if the code page is valid, or 0 if the code page is invalid. Remarks A code page is considered valid only if it is installed on the operating system. Unicode is preferred. Starting with Windows Vista, all code pages that can be installed are loaded by default. |
Сообщ.
#4
,
|
|
|
Цитата B.V. @ Цитата Eric-S @ И вдруг, когда стал указывать ей utf-16 le, utf-16 be, она выдала ошибку. А какую, если не секрет? Конкретно MultiByteToWideChar... |там у меня ретранслируются в std::system_error), заявила, что неверный параметр. А соответственно IsValidCodePage, возвращает FALSE. Попробовал вывести все установленные кодировки: ::EnumSystemCodePages( &output_proc, CP_INSTALLED ); Вывела много, есть 65001, 866, 1251, а вот utf16 и не нашёл. |
Сообщ.
#5
,
|
|
|
Цитата Eric-S @ Вывела много, есть 65001, 866, 1251, а вот utf16 и не нашёл. Открываем редактор Far, создаем "левый" текстовой файл, переключаем кодировку [Shift+F8] и наблюдаем интересующие: UTF-16 (Little endian) 1200, UTF-16 (Big endian) 1201. Бинго. Потом гуглим, и находим подтверждение, вдруг Рошал был не честен. Нет, все ровно |
Сообщ.
#6
,
|
|
|
Цитата Eric-S @ Делаю маленькую тулзу. Обычный MultiByteToWideChar и всё такое. И вдруг, когда стал указывать ей utf-16 le, utf-16 be, она выдала ошибку. Полагаю, что так и должно быть. Эта функция преобразует ASCII-строку в UTF-16. А WideCharToMultiByte - наоборот. Про UTF-16 они уже знают, это указывать не надо. --- Если EnumSystemCodePages не находит UTF-16, значит так оно и есть. Вот Enumerating System Code Pages посмотри пример. |
Сообщ.
#7
,
|
|
|
Цитата JoeUser @ и наблюдаем интересующие: UTF-16 (Little endian) 1200, UTF-16 (Big endian) 1201 Дык, всё так. Но почему-то сломалось. Может я винду тавокнул и потерял несколько кодировок. Добавлено Цитата ЫукпШ @ Полагаю, что так и должно быть. Нет. так не должно быть. Ибо: во-первых внутреннее представление, не обязательно utf16le. Оно вобще когда-то было uc-2. Во-вторых, конвертировать в utf16le из utf16be тоже надо. Ну и в добавок, всё выше написаное касается не только utf-16 но и utf-32. Оно тоже не работает! |
Сообщ.
#8
,
|
|
|
Цитата Eric-S @ Делаю маленькую тулзу. Обычный MultiByteToWideChar и всё такое. Цитата Eric-S @ Может я винду тавокнул и потерял несколько кодировок. Eric-S, это конечно оффтопик, тем не менее ... подумай а надо ли оно тебе (привязываться к свойствам/возможностям установленной винды)? Допустим не только у тебя "такая винда" ... Я просто не помню как это в Win 8.1, на которой сейчас сижу, но помню, что в XP - локали типа UTF16* вроде бы не были установлены по умолчанию. Что в итоге имеем? Твоя тулза в некоторых случаях будет "говорить" нечто типа "Эй, товарисч, у тя винда не той системы!". Оно тебе надо? Если не надо - глянь уже готовую либу ICU, там должно все быть. Но народ люто ненавидит, впрочем как и я, эту либу - ибо она компилиться в 25-метровую библиотеку. Но все ж признают, мол для UTF16* лучших альтернатив пока нет. |
Сообщ.
#9
,
|
|
|
Цитата JoeUser @ Твоя тулза в некоторых случаях будет "говорить" нечто типа "Эй, товарисч, у тя винда не той системы! Ну и пусть говорит. Если не той, значит не той. Собственно это так, мелкая примочка для тулзы. Хотелось, чтоб она умела открывать файлы в разных кодировках. Но для работы хватает и utf-8 и даже cp-1251. Я опасался, в первую очередь того, что сам где-то накосячил и затупив, не понял, в чём именно. Хотя, как-то всё странно. Первый раз с такой фигнёй сталкиваюсь. Раньше всё работало. Или я немного иначе делал... Тащить стороннюю либу, тоже можно. Размер не пугает. Там же целая куча charset'ов вбита. Я даже восхищаюсь, как они смогли так много затолкать в столь скромный размер. Возможно, что они там, чего-нибудь тоже почикали, потеряв несколько кодировок. Ну и как говорится "умер Никодим, ну и хрен с ним". Зато моя мелкая тулза, на 500 строк кода, весом в 25 мегабайт будет смотрется солиднее. Гы-гы-гы. Добавлено На самом деле, давно её знаю. Но как-то привык, встроенными функциями конвертировать. Привычка, вторая натура. Но всё равно спасибо! |
Сообщ.
#10
,
|
|
|
Цитата Eric-S @ Тащить стороннюю либу, тоже можно. Размер не пугает. У меня есть сильные подозрения - что там махровый быдлокод! Только подозрения, утверждать ниче не могу. Но могу поразмышлять. В свое время я несколько лет изучал японский язык, и малеха знаний осталось. Почему вспомнил про японский? Просто "иероглифические" языки - самые толстые в плане "алфавита". Простая статистика. Школьный минимум по выпуску для японцев - около 10000 иероглифов. "Графоманы" могут использовать около 40000 шт. Максимум можно рассчитать так. "Ключевых" (их называют ключи) иероглифов около 200, ну пусть 255. Позиций во "слово образовании" - три, левый один, и максимум два правых. В итоге получаем 255*255*255 = 16 581 375. Если тупо строить таблицу соответствий - сразу приходит на ум битовый массив. Итого 16581375/8=2072672. Два метра! Не двадцать пять! Хорошо, берем китайскую письменность. Но и тут "сюрпризик" Иероглифы - те же "японские". А по сути наоборот. У японцев своей письменности нет - они используют "словообразующие" иероглифы именно китайские, только чтение свое. И тут, кстати, ньюанс. Составные иероглифы читаются "китайскими" "чтениями". Вот два "толстых" алфавита мы оценили. Про корейсие иероглифы - ниче сказать не могу, тупо не в курсе. Остальная письменность - в большей части алфавитная, с достаточно ограниченным алфавитом. Арабская вязь, письменность Тайланда, и пр.пр Вот такие размышления. Ну не должно быть там 25 метров!!! Ну не верю |
Сообщ.
#11
,
|
|
|
Цитата Eric-S @ Добавлено Цитата ЫукпШ @ Полагаю, что так и должно быть. Нет. так не должно быть. Ибо: во-первых внутреннее представление, не обязательно utf16le. Оно вобще когда-то было uc-2. Во-вторых, конвертировать в utf16le из utf16be тоже надо. Ошибаешься. Можно посмотреть документацию на "MultiByteToWideChar" и понять, что она может и для чего нужна. А то, что надо конкретному юзеру, это его частные проблемы. Удовлетворять все возможные потребности эта функция не обещала. |
Сообщ.
#12
,
|
|
|
Цитата JoeUser @ Про корейсие иероглифы - ниче сказать не могу... Я слышал, что там всё те же самые китайские иероглифы. Они у них все одинаковые. Сотни дальневосточных народов, сотни диалектов, сотни выговоров, но письменность одна. Правда, у корейцев, собственный язык, и для него есть собственный, параллельный алфавит из 24 символов. Но буквы стилизованы под иероглифы. Но, кхе... icu, а точнее unicode, разрабатывали кто попало и как попало. Это уж точно. Так что, сомневаюсь, что там, может быть какая-либо система. Даже нашу кирилицу и то добавляли кусками. Букву "ё" засунули в зад, а церковнославянские символы, вообще только недавно начали добавлять в пятую версию. Ну и ожидаемо, что такое можно конвертировать только в лоб, суровым индуским быдлокодом. Добавлено Цитата ЫукпШ @ А то, что надо конкретному юзеру, это его частные проблемы. Удовлетворять все возможные потребности эта функция не обещала. Мне собственно нужно: 1. считать текстовый файл. Скоррее всего он будет в ansi, возможно в utf-8. 2. преобразовать кодировку хранения, в широкие символы LPWSTR. 3. выполнить декомпозиционную нормализацию. 4. обработать текст. 5. и записать его в файл в кодировке utf-8 или ansi по выбору пользователя. По моему MultiByteToWideChar тут подходит в самый раз. |
Сообщ.
#13
,
|
|
|
Цитата Eric-S @ Я слышал, что там всё те же самые китайские иероглифы. Не не не ... у корейцев - что то корейское Китайские иероглифы я б даже в печатной стилизации распознал. Там свое. |
Сообщ.
#14
,
|
|
|
Цитата JoeUser @ Не не не ... у корейцев - что то корейское Китайские иероглифы я б даже в печатной стилизации распознал. Там свое. У них две письменности. Но китайские иероглифы тоже юзают. http://ru.wikipedia.org/wiki/%D0%A5%D0%B0%D0%BD%D1%87%D0%B0 А так, в основном конечно юзают свою поделку https://ru.wikipedia.org/wiki/%D0%A5%D0%B0%...%8B%D0%BB%D1%8C |
Сообщ.
#15
,
|
|
|
Цитата Eric-S @ Мне собственно нужно: 1. считать текстовый файл. Скоррее всего он будет в ansi, возможно в utf-8. 2. преобразовать кодировку хранения, в широкие символы LPWSTR. 3. выполнить декомпозиционную нормализацию. 4. обработать текст. 5. и записать его в файл в кодировке utf-8 или ansi по выбору пользователя. По моему MultiByteToWideChar тут подходит в самый раз. Да, это возможно. Могу рекомендовать сделать класс-конвертер. |
Сообщ.
#16
,
|
|
|
Цитата ЫукпШ @ Да, это возможно. Могу рекомендовать сделать класс-конвертер. Спасибо, кэп! Кхе-кхе, я вообще-то его сделал в самом начале. Даже два decoder и encoder. А скоро сделаю normalizer. Сейчас делал поддержку bom. Именно для bom и требовались номера кодировок. О, кстати, там у меня есть одно reinterpret_cast, при конвертации. Я вместо LPCSTR указываю LPCBYTE. Но, из-за этого, думаю, ничего не сломается. |
Сообщ.
#17
,
|
|
|
Цитата Eric-S @ У них две письменности. Но китайские иероглифы тоже юзают. http://ru.wikipedia.org/wiki/%D0%A5%D0%B0%D0%BD%D1%87%D0%B0 А так, в основном конечно юзают свою поделку https://ru.wikipedia.org/wiki/%D0%A5%D0%B0%...%8B%D0%BB%D1%8C Ясно) Но по "нашему вопросу" это еще лучче - ибо выявили подмножество. |
Сообщ.
#18
,
|
|
|
Цитата JoeUser @ Ясно) Но по "нашему вопросу" это еще лучче - ибо выявили подмножество. Было бы лучше, если бы юникод закладывался по правилам. Впрочем, лично мне на эти иероглифы пофиг. Меня из них интересует, лишь символ пробела и конца предложения. Хорошая идея. Жаль, что в русском языке такого нет. А так.. Для своей тулзы, я могу и ручками правила конвертации задать. 1-байтовую кодировку перегнать в широкие символы просто. А вот с utf-8,, и ещё некоторыми, опасаюсь, что возникнут проблемы. Какой-то там алгоритм, немного странный. |
Сообщ.
#19
,
|
|
|
Eric-S, мы пока ходим вокруг-да-около. Предлагаю прагматичный вариант. Ты выкатывашь человечное описание проблемы и набросок ТЗ, а мы все вместе ищем ... либо выходы, либо обсуждаем реализацию. Если действительно игра будет стоить свеч - в результате все будем в профите, получим полезную либу. Имхо, этот вариант, стоит обсуждения.
|
Сообщ.
#20
,
|
|
|
Цитата JoeUser @ Она ещё и жутко медленная.Но народ люто ненавидит, впрочем как и я, эту либу - ибо она компилиться в 25-метровую библиотеку. Цитата JoeUser @ Там не символы, на кой хрен их там хранить, это забота шрифтов, там алгоритмы. А вот алгоритмов куда больше языков и их диалектов. Вот такие размышления. Ну не должно быть там 25 метров!!! |
Сообщ.
#21
,
|
|
|
Цитата Qraizer @ Там не символы, на кой хрен их там хранить, это забота шрифтов, там алгоритмы. А вот алгоритмов куда больше языков и их диалектов. Да речь не о шрифтах. Алгоритм перекодировки можно реализовать "нативным" кодом, либо тупо перебором "таблиц соответствия". Что там сделано, положа лапу на сердце - не знаю. Но размер либы напрягает. |
Сообщ.
#22
,
|
|
|
Цитата Eric-S @ Даже два decoder и encoder. Весьма неудачное решение. Нужен конвертер, т.е. объект, предоставляющий услуги типа: char_2_wchar, wchar_2_char, char_2_utf8, tchar_2_char итд, итп. Бессмысленно на кажддый вариант делать свою сущность. Достаточно одной на все преобразования. |
Сообщ.
#23
,
|
|
|
JoeUser, у тебя какой-то наивный подход к универсальной библиотеке по работе с юникодом. Перекодировка – только лишь малая часть функционала и не самая важная. Подумай, как, к примеру, задать правила преобразования регистров символов или регистронезависимого сравнения строк. Даже для простой латиницы будут десятки вариантов в зависимости от языка и национальных предпочтений.
|
Сообщ.
#24
,
|
|
|
Цитата Qraizer @ Даже для простой латиницы будут десятки вариантов в зависимости от языка и национальных предпочтений. 26*10= 260 вариантов, иче? Не буду брать на себя роль лигвиста, но в "иероглифических" алфавитах такой вопрос не стоит. Для латиницы - такие преобразования, имхо, пыль, по сравнению с 25 метрами либы. |
Сообщ.
#25
,
|
|
|
Рискну предположить, что фонетическое письмо забирает %66,(6) из этих метров. Одна только диакритика применительно к лексикографический сортировке может удвоить размеры таблиц соответствия, если не учетверить при оптимизации по производительности. А если ещё учесть различные местные диалекты одного и того же языка... нормандских диалектов, к примеру, существует около десятка, французских - не менее трёх итп. В турецком вон вообще все четыре I имеются, а в грузинском преобразование регистра несимметричное. Та вон, элементарно, попробуй правильно учесть ё в русском, когда вместо неё то и дело е пишут. Без этого сортировка будет неправильно располагать "неё" и "неестественно".
В общем, я вполне верю, что эти мегабайты в целом оправданы. И если там и есть, что соптимизировать, то результат будет не сильно-то впечатляющим. |
Сообщ.
#26
,
|
|
|
Цитата Qraizer @ Рискну предположить, что фонетическое письмо забирает %66,(6) из этих метров. Ну сейчас там такие расклады: Цитата ICU Data Size |
Сообщ.
#27
,
|
|
|
Цитата Eric-S @ А вот с utf-8,, и ещё некоторыми, опасаюсь, что возникнут проблемы. Какой-то там алгоритм, немного странный. Строение кодов UTF-8 достаточно простое. Коды, начинающиеся c 0 соответствуют ASCII-кодам, то есть их UNICODE значение совпадает с младшими 7 битами. Коды, начинающиеся с шести единиц стартуют шестибайтовые последовательности. В этом байте используется два младших бита. На практике старший из них всегда равен нулю. Коды, начинающиеся с 11 начинают многобайтовый символ, число старших единиц даёт число байт в символе, старшие единицы и следующий за ними ноль отбрасываются, остальные содержат старшие биты UNICODE Коды, начинающиеся с 10 являются кодами продолжения, младшие 6 бит содержат часть UNICODE значения Для образования символа UNICODE из многобайтового значимые биты всех байт соединяются в одну битовую строку и дополняются слева необходимым числом нулей. 6 байт (максимальная длина UTF-8) позволяет записать все 32-битные коды. Определённые на сегодня символы UNICODE всегда помещаются в три байта (хотя мои сведения может быть уже устарели). При записи подход обратный Коды меньшие 128 кодируются как ASCII Иначе значение UNICODE (без стартовых нолей) разбивается справа на группы по шесть разрядов. Если число в левой ненулевой группе не помещается в стартовый байт соответствующей последовательности, слева добавляется одна нулевая группа. Группы снабжаются заголовками и записываются. При записи надо использовать наиболее короткое кодирование. При чтении проверять кодировку на наименьшую длину необязательно. |