Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.12.2007, 04:29   #1
PuzzleC
Пользователь
 
Регистрация: 01.11.2007
Сообщений: 33
По умолчанию как определить в какой кодировке текстовый файл?

как определить в какой кодировке текстовый фаул? например ANSI <-> ASCII
PuzzleC вне форума Ответить с цитированием
Старый 10.12.2007, 10:17   #2
Alek86
Форумчанин
 
Регистрация: 25.09.2007
Сообщений: 189
По умолчанию

думаю, никак
Alek86 вне форума Ответить с цитированием
Старый 10.12.2007, 10:55   #3
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

Цитата:
Сообщение от Alek86 Посмотреть сообщение
думаю, никак
Ну, почему-же. Можно. Набрать статистику распределения символов.
Для русского языка часто встречающиеся символы ОТЕНАР.
alexBlack вне форума Ответить с цитированием
Старый 10.12.2007, 11:05   #4
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

Вот схема:
объявляем два массива
WinCounts : array [char] of integer; // Количество символов в кодировке Win
DosCounts : array [char] of integer; // Количество сисволов в кодировке DOS

Очередную строку файла обработываем:

if length(S) = 0 then exit;

SetLength(S2, length(S));
OEMToChar(PChar(S), PChar(S2)); /// DOWtoWIN
S1 := Upper(S);
S2 := Upper(S2);
for i:=1 to length(S1) do begin
Inc(WinCounts[S1[i]]);
Inc(DosCounts[S2[i]]);
end;

т.е. увеличиваем количество символов в обеих кодировках.
Чем больше строк обработано, тем лучше, но достаточно даже одной строки.

После обработки части файла:

M := (WinCounts['О'] + WinCounts['Т'] + WinCounts['Е'] + WinCounts['H'] + WinCounts['А']);
if (DosCounts['О'] + DosCounts['Т'] + DosCounts['Е'] + DosCounts['H'] + DosCounts['А']) > M
then CodePage := cpDOS;
alexBlack вне форума Ответить с цитированием
Старый 10.12.2007, 12:25   #5
Alek86
Форумчанин
 
Регистрация: 25.09.2007
Сообщений: 189
По умолчанию

это не 100% вариант, думаю (хотя спорить не хочется)
Alek86 вне форума Ответить с цитированием
Старый 11.12.2007, 05:55   #6
PuzzleC
Пользователь
 
Регистрация: 01.11.2007
Сообщений: 33
По умолчанию

[b]alexBlack[b] видите ли в чем дело, мне нужно переводить из DOS кодировки в Win но я не знаю в какой кодировке пребывает файл в данный момент. Функция OEMToChar переводит (и непереводит если это не надо, хотя не уверен не тестировал ) например считав строку из файла прогоняю ее через OEMToChar и она меняется если эта строка в DOS кодировке и не меняется если в WIN кодировке! Я хочу добиться именно такого эффекта, я написал свою функцию OEMToChar, но если строка уже в Win код-ке она искажает символы входящие в диапазон от 'р'до 'я'
PuzzleC вне форума Ответить с цитированием
Старый 11.12.2007, 08:32   #7
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

Цитата:
Сообщение от PuzzleC Посмотреть сообщение
[b]alexBlack[b] видите ли в чем дело, мне нужно переводить из DOS кодировки в Win но я не знаю в какой кодировке пребывает файл в данный момент. Функция OEMToChar переводит (и непереводит если это не надо, хотя не уверен не тестировал ) например считав строку из файла прогоняю ее через OEMToChar и она меняется если эта строка в DOS кодировке и не меняется если в WIN кодировке! Я хочу добиться именно такого эффекта, я написал свою функцию OEMToChar, но если строка уже в Win код-ке она искажает символы входящие в диапазон от 'р'до 'я'
То есть я не достаточно подорбно объяснил. Итак. Сначала нужно узнать в какой кодировке файл. Для этого его нужно просканировать (или хотя-бы несколько строк). Для каждой строки файла S

S1 = upper(S) - исходная строка
S2 = upper(OEMtoChar(S)) - та же строка в другой кодировке

Мы используем только верхний регистр символов, т.к. нас интересует частота встречаемости.

Увеличиваем количество символов
for i:=1 to length(S1) do begin
Inc(WinCounts[S1[i]]);
Inc(DosCounts[S2[i]]);
end;

Когда все строки проанализированы, проверяем частоты встречаемости символов ОТЕНАР в обеих кодировках

M := (WinCounts['О'] + WinCounts['Т'] + WinCounts['Е'] + WinCounts['H'] + WinCounts['А']);

if (DosCounts['О'] + DosCounts['Т'] + DosCounts['Е'] + DosCounts['H'] + DosCounts['А']) > M
then CodePage := cpDOS;
else CodePage := cpWIN;

И уже теперь, если cpDOS, то переводим строку в кодировку WIN.

Как уже было замечено, 100% определения не достигнуть. Но, по моим наблюдениям такой алгоритм правильно срабатывал по одной строке.

Надеюсь, я достаточно понятно объяснил.
alexBlack вне форума Ответить с цитированием
Старый 11.12.2007, 13:52   #8
PuzzleC
Пользователь
 
Регистрация: 01.11.2007
Сообщений: 33
По умолчанию

Извиняюсь за тупость но довольно туманна суть алгоритма. Одно и то-же слово может иметь смысл при правильной конвертации chartooem и быть просто набором символов в том случае если конвертировать было и не надо, тогда обычная встречаемость символов это очень убогое подобие смыслового анализа? Я правдо на деле еще не испытывал сей алгоритм...
Все может быть...
PuzzleC вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
текстовый файл werser Общие вопросы Delphi 3 06.06.2008 08:42
Текстовый файл subsonic Общие вопросы Delphi 5 09.03.2008 21:20
текстовый файл Var17 Общие вопросы Delphi 1 22.12.2007 02:20
Текстовый файл в текстовый массив Kimimaru Общие вопросы C/C++ 1 02.12.2007 11:55
как из Delphi определить под какой учетной записью осуществлен вход в систему zetrix Безопасность, Шифрование 1 29.10.2006 11:14