convertion UTF8 to ANSI

Тема в разделе "WASM.WIN32", создана пользователем ATX, 10 авг 2009.

  1. ATX

    ATX New Member

    Публикаций:
    0
    Регистрация:
    7 ноя 2006
    Сообщения:
    145
    Доброго времени суток ув. форумчане!
    Сразу прошу пардрна за затертую тему, в этом топике хочу завершить ее раз и навсегда)

    Покопался по форуму, нашел код как можно выполнить конвертацию UTF8 -> ANSI, но почему-то результат конвертации не верный.
    Что интересно, почему-то не конвертируется русские буквы, на выходе получаю знаки вопроса...
    Подскажите плиз, что я делаю не так!?

    Код (Text):
    1. Utf8ToAnsi proc lpString:DWORD, szString:DWORD, lpBuffer:DWORD
    2.      mov esi, lpString
    3.      mov ecx, szString
    4.      repne scasb
    5.      neg ecx
    6.      add ecx, szString
    7.      push ecx
    8.      invoke    MultiByteToWideChar,CP_UTF8,0,lpString,ecx,lpBuffer,eax
    9.      pop    ecx
    10.      shl    ecx, 2
    11.      invoke    WideCharToMultiByte,CP_ACP,0,lpBuffer,ecx,lpString,szString,0,0
    12.      ret
    13. Utf8ToAnsi endp
     
  2. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    а конечную кодировку используешь 1251?
     
  3. ATX

    ATX New Member

    Публикаций:
    0
    Регистрация:
    7 ноя 2006
    Сообщения:
    145
    shoo,

    Кодировку не выставлял, поскольку не могу знать на каком яз. набран конвертируемый текст в UTF8, а указав русский значит обламаться с другими яз.
    И еще вопрос - как определить в какой кодировке текст utf8/utf16/...?
     
  4. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    на кой черт вам сдалось это utf8/utf16. чем плох чистый unicode big/little-endian
     
  5. djmans

    djmans New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2006
    Сообщения:
    312
    utf8/utf16 вообшето это уневерсальноая кодировка под любые языки. Чтоб отпали все вопросы почитай при них на википедии например.
    пашет кода предпололу что в винде выставлена не 1251 кодировка по умочланию. попробуй в параметре WideCharToMultiByte вместо CP_ACP прописать число 1251, если не поможет проблема в тебе.
     
  6. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    djmans
    они-то универсальные, но смысла в них нет. чистый уникод, а экономить 1 байт на англ. текстах - нацизм!
     
  7. ATX

    ATX New Member

    Публикаций:
    0
    Регистрация:
    7 ноя 2006
    Сообщения:
    145
    Ув. коллеги!

    Вопрос не в том, юзать или не юзать кодировку utf8, ее заюзали до меня, а вот мне как раз и нужно ее перевести в ansi (включая 1257 и др. кодовые раскладки).

    1257 вместо CP_ACP конечно подставлял - результат был тот же :dntknw:
    Кстати я вообще не понимаю смысла этого параметра, при конвертации из юникода, не правда ли странный параметр!?!?

    Собственно вот это меня и беспокоит, что в такой не сложной задачке не получается разобраться, если кто подскажет в чем загвоздка - буду очень и очень признателен!!!
     
  8. djmans

    djmans New Member

    Публикаций:
    0
    Регистрация:
    27 дек 2006
    Сообщения:
    312
    >Кстати я вообще не понимаю смысла этого параметра, при конвертации из юникода, не правда ли странный параметр!?!?
    ты конвиртируеш юникод в однобайтовыю кодировку, в одном байте нельзя уместить все возможные языковые символы мира, поэтому происходит конвертация из интернациональной кодировки в локальную(установленую в винде) однобайтовую устанвелную через CP_ACP(меняется в ~control panel->regional settings).

    Покажи текст в hex'e, который конвертируеш, может в нем проблема.
     
  9. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    кодировку можно попытаться "угадать" по первому не-ASCII (0-127) символу. не скажу за utf8, но, например, в юникоде если старший байт 04h - значит кириллица, и т.п.
    но всё равно - если ты сам не определишь подходящую страницу - ф. мультибайтВанси тем более не будет этим заниматься. а если ютф8 содержит символы, соответствующие разным кодовым страницам - без потерь не обойтись.
     
  10. ATX

    ATX New Member

    Публикаций:
    0
    Регистрация:
    7 ноя 2006
    Сообщения:
    145
    Нифига не понимаю, по логике вещей конвертация должна происходить, но русский не хочет конвертить.
    Даже балтийский и немецкий без вопросов транслирует(((
     
  11. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Параметр определяет кодовую страницу выходного текста. Допустим, wide-char текст (который в винде зачастую называют просто "Юникод" и который по сути являестя UTF16-LE) содержит слова "кошка 日本国". Тогда при вызове функции WideCharToMultiByte(1251,..) на выходе мы получим текст "кошка ???" (символы, которым не найдено соответсвие в выходной кодовой таблице, заменены на "?").


    Необходимость видеть полный код и сырые входные данные.
     
  12. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    А, теперь всё есть, видим.

    Код (Text):
    1. Utf8ToAnsi proc lpString:DWORD, szString:DWORD, lpBuffer:DWORD
    2.      mov esi, lpString
    3.      mov ecx, szString
    4.      repne scasb
    5.      neg ecx
    6.      add ecx, szString
    7.      push ecx
    8.      invoke    MultiByteToWideChar,CP_UTF8,0,lpString,ecx,lpBuffer,eax              <<<<<<
    9.      pop    ecx
    10.      shl    ecx, 2
    11.      invoke    WideCharToMultiByte,CP_ACP,0,lpBuffer,ecx,lpString,szString,0,0
    12.      ret
    13. Utf8ToAnsi endp
    Длина строки указывается в символах – не в байтах. Можно указать '-1'.
    То же и для обратного преобразования.

    А вообще лучше всего, как уже сказали, преобразовать код так, чтобы работать только с юникодом и избавится от кодовых таблиц вообще.
     
  13. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    Код (Text):
    1.     invoke MultiByteToWideChar,CP_UTF8,0,ibuff,-1,tbuff,512
    2.     invoke WideCharToMultiByte,1251,0,tbuff,-1,obuff,1024,0,0
     
  14. ATX

    ATX New Member

    Публикаций:
    0
    Регистрация:
    7 ноя 2006
    Сообщения:
    145
    Списибо shoo!

    Теперь вопрос, как же мне достоверно определить в какую кодировку конвертить?
    Ведь если текст будет не на русском яз. и я укажу пареметр 1251 то будет ошибочная конвертация(
     
  15. s0larian

    s0larian New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    489
    Адрес:
    Крыжёпполь
    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
     
  16. ATX

    ATX New Member

    Публикаций:
    0
    Регистрация:
    7 ноя 2006
    Сообщения:
    145
    s0larian,

    Публикация на эту тему хорошая, спасибо!
    Но вопрос не в понимании "Who is who?", вопрос в практическом применении, а еще точнее в непосредственной конвертации.

    Я понимаю что unicode (all wide) не тоже самое что ansi (and char types...) и даже хорошо понимаю их разницу по факту.

    Но елки-палки, если при конвертации в ANSI нужно указывать конкретную кодовую страничку, каким образом ее можно узнать по входному юникоду, или это в принципе невозможно?

    Собственно вот в чем вопрос!
     
  17. s0larian

    s0larian New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    489
    Адрес:
    Крыжёпполь
    Их данных - никаким. В GUI прогах есть либо установки (options) либо смотрят default system locale или current system locale.
     
  18. ATX

    ATX New Member

    Публикаций:
    0
    Регистрация:
    7 ноя 2006
    Сообщения:
    145
    Виноват, не пояснил смысл задачи, ща подправим)
    Мне нужно скачать web-странички и если они в юникод формате, их нужно привести к единому формату для дальнейшей обработки, в данном случае ANSI.

    Идти от обратного, т.е. конвертировать из ANSI+code page в юникод не рационально, поскольку страничек у юникоде гораздо меньше чем в ANSI...

    Вот и как тут корректно все выстроить!?
     
  19. reverser

    reverser New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2004
    Сообщения:
    615
    В общем случае текст в юникоде невозможно уместить в какую-то выбранную ANSI страницу.
     
  20. Stiver

    Stiver Партизан дзена

    Публикаций:
    0
    Регистрация:
    18 дек 2004
    Сообщения:
    812
    Адрес:
    Germany
    ATX
    А что например делать, если страница содержит одновременно русские буквы и немецкие спецсимволы ä,ö,ß и т.д.? Такой кодовой страницы для ANSI не существует.