- Маша, давай прошвырнемся в кино?
- ?
- Hу давай хоть в кабак сходим.
- ? - А-а, понял, кодировка глючит...
const
l3_csANSI = 0;
{-признак кодировки ANSII}
l3_csOEM = 255;
{-признак кодировки OEM}type
cc_Graph_CriteriaRange = #176..#223; {-критерий для определения псевдографики}
TChars = setof char;
Long = LongInt;
const
cc_OEM_CriteriaEx = [#128..#175] + [#224..#239];
cc_ANSI_CriteriaEx = [#192..#255];
cc_Graph_Criteria = [Low(cc_Graph_CriteriaRange)..High(cc_Graph_CriteriaRange)];
type
T_cc_GraphCounts = array [cc_Graph_CriteriaRange] of Longint;
procedure l3AnalizeCharSetEx(var Buf: PChar; BufEnd: PChar;
var OEMCount, ANSICount, GraphCount: Long;
var GraphCounts: T_cc_GraphCounts);
var
C : Char;
begin
OEMCount := 0;
ANSICount := 0;
GraphCount := 0;
for C := Low(T_cc_GraphCounts) to High(T_cc_GraphCounts) do GraphCounts[C] := 0;
while (Buf < BufEnd) dobegin
C := Buf^;
Inc(Buf);
if (C in cc_OEM_CriteriaEx) then Inc(OEMCount);
if (C in cc_ANSI_CriteriaEx) then Inc(ANSICount);
if (C in cc_Graph_Criteria) thenbegin
Inc(GraphCounts[C]);
Inc(GraphCount);
end;
end;{Buf < BufEnd}end;
function l3AnalizeCharSetExEx(Buf, BufEnd: PChar): Byte;
var
OEMCount : Long;
ANSICount : Long;
GraphCount : Long;
GraphCount_2: Long;
GraphCounts : T_cc_GraphCounts;
C : Char;
begin
l3AnalizeCharSetEx(Buf, BufEnd, OEMCount, ANSICount, GraphCount,GraphCounts);
if (OEMCount > ANSICount) then
Result := l3_csOEM
elseif (GraphCount > = ANSICount) thenbegin
Result := 0;
GraphCount_2 := GraphCount div 2;
for C := Low(T_cc_GraphCounts) to High(T_cc_GraphCounts) dobeginIf (GraphCounts[C] > GraphCount_2) thenbegin
Result := l3_csOEM;
break;
end;{GraphCounts[C] > ..}end;{for C}endelse Result := 0;
end;
function l3AnalizeCharSetBuf(Buf: PChar; Len: Long): Byte;
begin
Result := l3AnalizeCharSetExEx(Buf, Buf + Len);
end;
Программа на языке Pascal, которая пытается автоматически обнаружить кодировку (шарcter set) входного буфера. Вот разбивка кода:
Константы и типы
l3_сsANSI и l3_сsOEM - константы, представляющие собой ANSI и OEM шарcter sets соответственно.
cc_Graph_CriteriaRange - тип, представляющий диапазон символов, используемых для определения является ли шарcter set графическим или нет.
TChars - множество символов.
Long - псевдоним для LongInt, который является 32-битным целым типом.
Константы
cc_OEM_CriteriaEx и cc_ANSI_CriteriaEx - множества символов, используемых для определения является ли шарcter set OEM или ANSI соответственно.
cc_Graph_Criteria - множество символов, используемых для определения является ли шарcter set графическим или нет.
Процедура
l3AnalizeCharSetEx: эта процедура анализирует кодировку входного буфера. Она принимает пять параметров: Buf, BufEnd, OEMCount, ANSICount и GraphCount. Процедура инициализирует счетчики для OEM, ANSI и графических символов, а затем проходит по буферу, увеличивая соответствующие счетчики в зависимости от найденных символов.
Функция
l3AnalizeCharSetExEx: эта функция является расширением l3AnalizeCharSetEx, которая возвращает значение, указывающее, является ли шарcter set OEM или ANSI. Она вызывает l3AnalizeCharSetEx и затем проверяет результаты для определения, какой кодировки более распространен.
Если символов OEM больше, функция возвращает l3_сsOEM.
Если графические символы более распространены, чем симвols ANSI, функция возвращает 0, указывая, что шарcter set вероятно OEM.
В противном случае функция возвращает 0, указывая, что шарcter set вероятно ANSI.
Функция
l3AnalizeCharSetBuf: эта функция является оберткой вокруг l3AnalizeCharSetExEx, которая принимает входной буфер и его длину как параметры. Она вызывает l3AnalizeCharSetExEx с входным буфером и его конечной адрессой, а затем возвращает результат.
В целом, эта программа использует комбинацию критериев для попытки автоматического обнаружения кодировки входного буфера. Критерии включают:
1. Наличие символов OEM (например, #128..#175, #224..#239)
2. Наличие символов ANSI (например, #192..#255)
3. Преобладание графических символов (например, cc_Graph_Criteria)
Программа возвращает значение, указывающее, является ли шарcter set вероятно OEM или ANSI.
Альтернативное решение:
Вместо использования комбинации критериев можно рассмотреть использование болееadvanced techniques, такие как:
1. Использование библиотеки ICU (International Components for Unicode), которая предоставляет robust character set detection capabilities.
2. Реализация более sofisticated алгоритма, использующего машинное обучение или статистический анализ для обнаружения кодировки на основе паттернов в входном буфере.
Обратите внимание, что обнаружение кодировки может быть сложным и нюансами, и полагаться только на эту программу может не всегда привести к точным результатам.
Автоопределение кодировки ANSI-OEM - статья, в которой описывается алгоритм определения кодировки текста по анализу символов.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.