Сконвертировать ascii в unicode "in place"

Тема в разделе "WASM.BEGINNERS", создана пользователем katrus, 31 дек 2008.

  1. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Не могу найти подходящий метод. Все виндосовские функции "хотят" использовать другой буфер для вывода. Тупое добавление нулей не всегда работает, например, когда в тексте присутствуют русские буквы.
     
  2. AndreyMust19

    AndreyMust19 New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2008
    Сообщения:
    714
    Прежде чем переводить, нужно указать - в какой Ascii-кодировке наш текст. Ну а потом переводить отдельно для каждой кодировки. Лучше всего составить таблицу всех Unicode-символов и отдельные таблицы для каждой кодировки, которые будут указывать - каким символам Unicode-таблицы они соответствуют.
    Для этого должны быть WinAPI-функции - если не нравятся - пиши собственные.
     
  3. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    katrus
    с русскими буквами всё просто
    Код (Text):
    1. ;-----------------------------------------------------------------------------
    2. ;   Определяет UNICODE строку
    3. sUNICODE MACRO ANSI_String
    4.   % IRPC A_Char, <ANSI_String>
    5.     IFE ("&A_Char&" - 27h)  ; <- игнорировать символы кавычек ''
    6.     ELSEIFE ("&A_Char&" and 80h)    ; <= 7Fh - цифры и латиница
    7.         db "&A_Char&", 0h
    8.     ELSEIFE (("&A_Char&" and 0C0h) - 0C0h)  ; >= 0C0h Кириллица
    9.         db ("&A_Char&" - 0B0h), 04h
    10.     ELSEIFE ("&A_Char&" - 0A7h) ; §
    11.         db 0A7h, 0h
    12.     ELSEIFE ("&A_Char&" - 0A8h) ; Ё
    13.         db 01h, 04h
    14.     ELSEIFE ("&A_Char&" - 0A9h) ; ©
    15.         db 0A9h, 0h
    16.     ELSEIFE ("&A_Char&" - 0B8h) ; ё
    17.         db 051h, 04h
    18.     ELSEIFE ("&A_Char&" - 0B9h) ; №
    19.         db 016h, 21h
    20.     ELSEIFE ("&A_Char&" - 0AEh) ; ®
    21.         db 0AEh, 0h
    22.     ELSEIFE ("&A_Char&" - 0B0h) ; °
    23.         db 0B0h, 0h
    24.     ELSEIFE ("&A_Char&" - 0B1h) ; ±
    25.         db 0B1h, 0h
    26.     ENDIF
    27.     ENDM
    28. ENDM
    но для полной универсальности своих функций кури официальные стандарты на уникод :)
     
  4. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Y_Mur

    Спасибо, но хотелось бы что то более общее, подходящее и для других языков. Странно, что нет функции конвертирующей один единственный юникод символ.
     
  5. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    katrus
    "двухбуферный" вариант нужен чтобы не копировать весь хвост строки при расширении\сужении каждого символа :), если нужен однобуферный вариант - стандартный приём - сделать обёртку с временным буфером, который потом скопируешь в исходный - одно копирование буфера полюбому быстрее многократного копирования "хвостов" ;)
    вызывать extern функцию для каждого символа тоже не дзен (другое дело inline функция, но её смотри в сорцах, а не среди api ;). Для "упрощённого" преобразования см. ключики %C и %W в wsprintf, но у меня большое подозрение что она всё равно вызывает MultiByteToWideChar или WideCharToMultiByte (и тоже требует выходного буфера с местом под завершающий 0), так что если не нужна "вся мощь" wsprintf, лучше сделай свою обёртку.
     
  6. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Вопрос: всегда ли один символ в юникодной строке соответствует строго одному в аски?
     
  7. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    katrus
    конечно, только ширина символа разная.
    Кстати при сужении (WideCharToMultiByte) по идее должно сработать и если указать в качестве входного и выходного параметра один и тот же адрес, да и при расширении (MultiByteToWideChar) если символ только один это тоже должно сработать, но проверять лень да и с мультивиндовостью этого варианта вопрос неоднозначный, хотя если там всё сделано логично, то должно работать везде.
     
  8. Ursus

    Ursus Member

    Публикаций:
    0
    Регистрация:
    15 мар 2006
    Сообщения:
    238
    Адрес:
    Russia
    Что ви говорите :)
     
  9. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Ursus
    А ви имеете что-то возразить? или желаете уточнить про достаточно экзотический флаг WC_COMPOSITECHECK? - тогда лучше сказать "почти всегда" :))