DoctorLans
Member | Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору Господа, помогите разобраться с кодировками. Задача: одинаковым образом выводить русские символы в консоль как при разработке в SciTE, так и в готовом приложении. Ниже привожу свои действия и рассуждения. AutoIT последней версии, Windows 7 x64 Настройки SciTE: code.page=65001 output.code.page=866 первая (65001 это обозначение UTF-8 в винде) отвечает за кодировку исходного файла. Хранить исходники в UTF-8 мало что правильнее независимо от языка программирования, так ещё и рекомендуется самими разрабами AutoIT: Цитата: The recommended script format is UTF-8 with BOM. | вторая настройка, насколько я понимаю, отвечает за кодировку "консоли" SciTE. Выставил её такой же, как в самой винде. Простенький скрипт: Код: #include <Encoding.au3> $s = "Привет" ConsoleWrite($s & @CRLF) ConsoleWrite(_Encoding_ANSIToOEM($s) & @CRLF) | Запускаем. Вывод в самом SciTE: Снова рассуждения: AutoIT с момента появления Unicode версии хранит все строки во внутреннем представлении UTF-16. Цитата: All AutoIt strings use UTF-16 (in fact and more precisely UCS-2) encoding. | Но: Цитата: There are a few parts of AutoIt that don't yet have full Unicode support. These are: * Send and ControlSend - Instead, Use ControlSetText or the Clipboard functions. * Console operations are converted to ANSI. | По всей видимости при передаче строки в функцию ConsoleWrite, автоматически и неявно происходит её конвертация в однобайтовую кодировку ANSI (в русскоязычной винде это CP1251). Стоит признать, что неявно конвертировать, да с возможной потерей информации не совсем удачное решение, но сами разрабы признаются, что это недоработка и они её когда-нибудь пофиксят: Цитата: These limits will be addressed in future versions if possible. | Ну ладно. В функцию ConsoleWrite приходит CP1251, а в что происходит дальше, мне не совсем понятно. То ли SciTE подменяет ConsoleWrite своей реализацией, то ли как-то ещё меняет строку, но факт - срабатывает моя настройка output.code.page=866 и строка из ANSI (CP1251) кодировки преобразуется в OEM (866) и в таком виде успешно выводится на экран. Что касается второго вывода, с использованием функции _Encoding_ANSIToOEM, она заранее преобразует ANSI в OEM (866) и скармливает ConsoleWrite уже OEM строку. Но та, судя по всему, ожидает только ANSI (cp1251), соответственно интепретирует пришедшую как ANSI, как результат - кракозябры. Ладно, компилируем скрипт в exe: Aut2exe_x64.exe /in charset.au3 /out charset.exe /console кстати куда убрали галочку "конвертировать как консольное приложение" из GUI компилятора скриптов? Теперь приходится использовать только консольную версию Запускаем получившийся .exe: И тут неожиданно всё наоборот. Видимо в скомпилированной версии AutoIT скрипта ConsoleWrite почему-то начинает ожидать строку не в 1251, а уже в 866. Соответственно в верхнем выводе неявно преобразованная AutoIT'ом в ANSI (cp1251) интерпретируется неправильно. Нижний же вывод подтверждает, что почему-то ожидается 866. Ему подаётся на вход именно она, заботливо сконвертированная мной через _Encoding_ANSIToOEM, и выводится она правильно. Кстати заметил ещё одну странность. Вывод в SkiTE не зависит от того, поставить ли параметр output.code.page=866 или output.code.page=1251 или output.code.page=cp1251 Всё выводится однофигственно, как показано на первом скриншоте. Но если вообще убрать этот параметр, оставив только code.page=65001, то вывод в SkiTE сразу ломается и вместо ещё более-менее читабельных символов появляются байты: Ладно, "байты" ещё объяснимы вот этим: Цитата: If output.code.page is set then it is used for the output pane which otherwise matches the edit pane. | Но вот почему не влияет смена однобайтовой кодировки 866/1251, не понятно. Вопрос: все ли мои рассуждения верны? Второй вопрос: как таки добиться единообразного вывода и при разработке в SkiTE и в консоли Windows? | Всего записей: 248 | Зарегистр. 07-10-2006 | Отправлено: 21:54 12-03-2014 | Исправлено: DoctorLans, 22:29 12-03-2014 |
|