Доброго времени суток ув. форумчане! Сразу прошу пардрна за затертую тему, в этом топике хочу завершить ее раз и навсегда) Покопался по форуму, нашел код как можно выполнить конвертацию UTF8 -> ANSI, но почему-то результат конвертации не верный. Что интересно, почему-то не конвертируется русские буквы, на выходе получаю знаки вопроса... Подскажите плиз, что я делаю не так!? Код (Text): Utf8ToAnsi proc lpString:DWORD, szString:DWORD, lpBuffer:DWORD mov esi, lpString mov ecx, szString repne scasb neg ecx add ecx, szString push ecx invoke MultiByteToWideChar,CP_UTF8,0,lpString,ecx,lpBuffer,eax pop ecx shl ecx, 2 invoke WideCharToMultiByte,CP_ACP,0,lpBuffer,ecx,lpString,szString,0,0 ret Utf8ToAnsi endp
shoo, Кодировку не выставлял, поскольку не могу знать на каком яз. набран конвертируемый текст в UTF8, а указав русский значит обламаться с другими яз. И еще вопрос - как определить в какой кодировке текст utf8/utf16/...?
utf8/utf16 вообшето это уневерсальноая кодировка под любые языки. Чтоб отпали все вопросы почитай при них на википедии например. пашет кода предпололу что в винде выставлена не 1251 кодировка по умочланию. попробуй в параметре WideCharToMultiByte вместо CP_ACP прописать число 1251, если не поможет проблема в тебе.
djmans они-то универсальные, но смысла в них нет. чистый уникод, а экономить 1 байт на англ. текстах - нацизм!
Ув. коллеги! Вопрос не в том, юзать или не юзать кодировку utf8, ее заюзали до меня, а вот мне как раз и нужно ее перевести в ansi (включая 1257 и др. кодовые раскладки). 1257 вместо CP_ACP конечно подставлял - результат был тот же Кстати я вообще не понимаю смысла этого параметра, при конвертации из юникода, не правда ли странный параметр!?!? Собственно вот это меня и беспокоит, что в такой не сложной задачке не получается разобраться, если кто подскажет в чем загвоздка - буду очень и очень признателен!!!
>Кстати я вообще не понимаю смысла этого параметра, при конвертации из юникода, не правда ли странный параметр!?!? ты конвиртируеш юникод в однобайтовыю кодировку, в одном байте нельзя уместить все возможные языковые символы мира, поэтому происходит конвертация из интернациональной кодировки в локальную(установленую в винде) однобайтовую устанвелную через CP_ACP(меняется в ~control panel->regional settings). Покажи текст в hex'e, который конвертируеш, может в нем проблема.
кодировку можно попытаться "угадать" по первому не-ASCII (0-127) символу. не скажу за utf8, но, например, в юникоде если старший байт 04h - значит кириллица, и т.п. но всё равно - если ты сам не определишь подходящую страницу - ф. мультибайтВанси тем более не будет этим заниматься. а если ютф8 содержит символы, соответствующие разным кодовым страницам - без потерь не обойтись.
Нифига не понимаю, по логике вещей конвертация должна происходить, но русский не хочет конвертить. Даже балтийский и немецкий без вопросов транслирует(((
Параметр определяет кодовую страницу выходного текста. Допустим, wide-char текст (который в винде зачастую называют просто "Юникод" и который по сути являестя UTF16-LE) содержит слова "кошка 日本国". Тогда при вызове функции WideCharToMultiByte(1251,..) на выходе мы получим текст "кошка ???" (символы, которым не найдено соответсвие в выходной кодовой таблице, заменены на "?"). Необходимость видеть полный код и сырые входные данные.
А, теперь всё есть, видим. Код (Text): Utf8ToAnsi proc lpString:DWORD, szString:DWORD, lpBuffer:DWORD mov esi, lpString mov ecx, szString repne scasb neg ecx add ecx, szString push ecx invoke MultiByteToWideChar,CP_UTF8,0,lpString,ecx,lpBuffer,eax <<<<<< pop ecx shl ecx, 2 invoke WideCharToMultiByte,CP_ACP,0,lpBuffer,ecx,lpString,szString,0,0 ret Utf8ToAnsi endp Длина строки указывается в символах – не в байтах. Можно указать '-1'. То же и для обратного преобразования. А вообще лучше всего, как уже сказали, преобразовать код так, чтобы работать только с юникодом и избавится от кодовых таблиц вообще.
Код (Text): invoke MultiByteToWideChar,CP_UTF8,0,ibuff,-1,tbuff,512 invoke WideCharToMultiByte,1251,0,tbuff,-1,obuff,1024,0,0
Списибо shoo! Теперь вопрос, как же мне достоверно определить в какую кодировку конвертить? Ведь если текст будет не на русском яз. и я укажу пареметр 1251 то будет ошибочная конвертация(
ATX, перво-наперво прочитай внимательно статью: http://www.joelonsoftware.com/articles/Unicode.html вкратце: - unicode это набор символов (character set) - utf-8, UCS-2, и т.д. это кодировки (encoding) использование: - приём/передача по сети (или вызовы API) могут быть в utf-8 и проге нужно знать что она работает с этой кодировкой и не нужно знать о code pages - если используется ANSI (8 битов) то в верхней половине ASCII таблицы какие-то другие символы и проге надо знать code page для перевода - при работе на Windows есть два пути - Unicode и ANSI. В первом случае всё просто, во втором у системы надо запрашивать code page когда достаёшь текст из какого-то edit box-a
s0larian, Публикация на эту тему хорошая, спасибо! Но вопрос не в понимании "Who is who?", вопрос в практическом применении, а еще точнее в непосредственной конвертации. Я понимаю что unicode (all wide) не тоже самое что ansi (and char types...) и даже хорошо понимаю их разницу по факту. Но елки-палки, если при конвертации в ANSI нужно указывать конкретную кодовую страничку, каким образом ее можно узнать по входному юникоду, или это в принципе невозможно? Собственно вот в чем вопрос!
Их данных - никаким. В GUI прогах есть либо установки (options) либо смотрят default system locale или current system locale.
Виноват, не пояснил смысл задачи, ща подправим) Мне нужно скачать web-странички и если они в юникод формате, их нужно привести к единому формату для дальнейшей обработки, в данном случае ANSI. Идти от обратного, т.е. конвертировать из ANSI+code page в юникод не рационально, поскольку страничек у юникоде гораздо меньше чем в ANSI... Вот и как тут корректно все выстроить!?
ATX А что например делать, если страница содержит одновременно русские буквы и немецкие спецсимволы ä,ö,ß и т.д.? Такой кодовой страницы для ANSI не существует.