Приложение 2: русификация консольных приложений
Достаточно часто приходится слышать вопрос: «Почему при попытке использования в консольных приложениях кириллицы на экране появляется нечитаемый набор символов?» Причиной такой казуистики является особенность размещения наших национальных символов в таблицах OEM и ANSI. При работе в редакторе кода Delphi исходный код программы набирается в ANSI-кодировке, но при выводе на экран Windows использует таблицу OEM.
Обратите внимание на следующее. Во-первых, коды кириллицы в этих таблицах полностью не совпадают. Во-вторых, символы кириллицы в таблице OEM хранятся не последовательно. После символа «п» (код символа 175) следует несколько десятков символов псевдографики и только затем символ «р» (код символа 224). Символ «Е» вообще выбился из общей последовательности и оказался на позиции 240.
Почему мы вспомнили эти две таблицы символов? А потому, что консольное приложение предназначено для работы с таблицей OEM, но эту программу мы создаем в среде Windows и, более того, работаем в ней под управлением Windows – операционной системы, работающей с таблицей ANSI. Другими словами, при вводе русского символа «А» (код 192 в ANSI) наше консольное приложение воспримет его как символ псевдографики «L» (код 192 в OEM), т. к. код кириллического «А» в таблице OEM равен 128. Задача ясна: нам необходимо решить проблему преобразования кодов символов. Вот так (в соответствии со всем вышеизложенным) выглядит функция перевода ANSI-символа в кодировку OEM:
function ANSI_TO_ASC(ch:char):char;
var bt:byte;
Begin
bt:=Byte(ch);
Case bt of
168 : result:=CHAR(240); {Е}
184 : result:=CHAR(241); {е}
192..239 : result:=CHAR(bt-64); {символы от “А” до “п”}
240..255 : result:=CHAR(bt-16); {символы от “р” до “я”}
else result:=ch;
end;
end;
Обратите внимание: преобразованию подвергаются только коды символов русского алфавита, остальные символы проходят сквозь функцию без каких-либо изменений.
А так выглядит функция преобразования строки символов ANSI в строку OEM:
functionANSI_TO_ASC_String(st : string):string;
var ch:char;
i:cardinal;
Begin
Result:='';
for i:=1 to Length(st) do Result:=Result+ANSI_TO_ASC(st[i]);
end;
Для проверки работоспособности функций преобразования стоит повторить следующий код:
const S1='АБВГДЕЕЖ...Я';
S2='абвгдееж...я';
Begin
WriteLn(ANSI_TO_ASC_String(S1));
WriteLn(ANSI_TO_ASC_String(S2));
ReadLn;
End.
Наивно было бы полагать, что мы стали первопроходцами в вопросе русификации консольных приложений. В недрах операционной системы предусмотрена специальная функция, преобразующая строку из набора символов текущей региональной установки в набор символов OEM:
functionCharToOem(Source : PChar; Buf : Array of char) : Boolean;
В этом методе всего два параметра: Source – указатель на исходную строку, заканчивающуюся нулем, и Buf – массив назначения, в который будет перенесена строка в наборе символов OEM. Если вы собираетесь использовать функцию CharToOem() в своих проектах, то в строке uses указывайте модульWindows:
uses SysUtils, Windows;
const s='АБВГДЕЕЖ...Я';
varBuf : Array[0..255] of char;
Result : string;
Begin
WriteLn(s);
CharToOem(s,Buf);
Result:=StrPas(Buf);
WriteLn(Result);
ReadLn;
End.
Обратный метод называется OemToChar(). Познакомиться с ним можно в справочной системе Delphi.
Дата добавления: 2016-03-15; просмотров: 1444;