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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 08.07.2008, 12:36   #1
!evgen!
 
Регистрация: 03.03.2008
Сообщений: 3
По умолчанию Кодировка

есть файл txt в 1251 кодировке как перевести в 866 кодировку и обратно во время выполнения программы.
!evgen! вне форума Ответить с цитированием
Старый 08.07.2008, 12:42   #2
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

CharToOem(), CharToOemBuff()
OemToChar(), OemToCharBuff()
http://msdn.microsoft.com/en-us/libr...78(VS.85).aspx
Somebody вне форума Ответить с цитированием
Старый 08.07.2008, 12:45   #3
Роман Радер
Форумчанин
 
Аватар для Роман Радер
 
Регистрация: 16.12.2006
Сообщений: 859
По умолчанию

Очень часто при разработке программ которые в той или иной форме используют текст программисты сталкиваются с текстами различных кодировок. Данная заметка призвана в некоторой степени облегчить им жизнь и рассказать о работе с разными кодировками текста

Постановка задачи
Итак. У нас есть кириллический текст с наперед известной кодировкой:
cp1251 - Кодовая страница windows
iso8859-5 - iso-страница
koi8-u - Кодовая страница используемая практически во всех версиях в unix
mac-u - Страница используемая в macos
ruscii - или старая добрая codepage 866 известная всем жившим в период dos.
Теперь же нам требуется предоставить пользователю возможность прочесть этот текст в нормальном виде. Для этого нам надобно перевести текст с этой кодовой страницы в ту, которая используется системой в данный момент, а так как большинство читателей используют в своей повседневной жизни windows, то текст мы будем приводить в соответствие со стандартной кодовой страницей windows - cp1251.

Решение
Решение данной задачи не столько сложно в плане логическом, сколько в технологическом. Так как тем программистам, которые специально не занимались этой проблемой бывает довольно трудно отыскать ту или иную кодовую страницу, а потом с первого раза привести ее в "рабочий" вид.

Теперь пристально вглядевшись в таблицы кодировок (рис.1 - рис.5) мы замечаем, что вся разница в кодовых страницах начинает проявляться только для второй половины таблицы (т.е. для символов с кодами 128-255, которые и изображены на рисунках). Теперь нам только понадобится вручную сопоставить коды из каждой таблицы в соответствии с кодами текущей кодовой страницы (cp1251). (см. Листинг 1).

Сам алгоритм может варьироваться от програмиста к програмисту. Но суть его должна быть одна и та же: выбрать символ, просмотреть таблицу перекодировки и если найдено совпадение - заменить символ. Примерный код алгоритма перебора подан ниже:


Код:
for j:=1 to length(s) do
if byte(s[j])>=low(a) then
for i:=low(a) to high(a) do
begin
if byte(s[j])=i then
begin
s[j]:=a[i];
break;
end;
end;
Здесь:
s - строка текста, которую следует перекодировать
a - массив перекодировки символов из соответствующей кодировки в cp1251.
"Подводные камни"
Хотя приведенный алгоритм не смотря на простоту реализации и дает необходимый результат, но при прямом его использовании могут возникнуть некоторые несоответствия называемые "двойной перекодировкой". Так к примеру получается, если мы перетаскиваем текст (через буфер обмена) из какой-то программы работающей в кодировке koi8 в текстовый редактор (к примеру far - f4), Который в это время находится в режиме редактирования dos - текста (рис.6 - рис.7). Тот же эффект можно видеть и при любых других комбинациях кодировок. Как раз для этого в таких продвинутых в кодовом плане программах как thebat! предусмотрена "двойная перекодировка"(рис.8).

И конечно же не стоит упоминать о том что можно найти текст, разные части которого написаны в разных кодировках, или, что еще хуже, с использованием разных вариантов "двойной перекодировки". Все эти ухищрения отнюдь не облегчают проблему распознавания кодировок, и заставляют программистов искать более совершенные методы эвристического анализа текста.

Выводы
Конечно эта маленькая заметка не претендует на роль всеобъемлющего руководства для построения "мультикодовых" приложений. Она всего лишь маленький шаг направленный в сторону облегчения общения людей работающих в разных средах, использующих различные ОС и ПО. И конечно же основная работа для обеспечения поддержки программами различных кодировок, или даже поддержки автоматического распознавания кодировок, возлагается как всегда на Вас - разработчиков этих самых программ.

//если вы ссылаетесь на сторонний ресурс, то копировать/вставить делаем сюда + копирайт. zetrix
Вложения
Тип файла: txt source.txt (3.6 Кб, 151 просмотров)

Последний раз редактировалось zetrix; 08.07.2008 в 14:48.
Роман Радер вне форума Ответить с цитированием
Старый 08.07.2008, 12:54   #4
eoln
Старожил
 
Аватар для eoln
 
Регистрация: 26.04.2008
Сообщений: 2,689
По умолчанию

1 способ
Код:
function CONV(s:string;AnsiToOem_:boolean):string;   
var    
  i:integer;   
  ph:pchar;   
  length_:integer;   
begin   
    length_:=length(s);   
    result:='';   
    if length_=0 then exit;   
    for i:=0 to length_ div 16 do begin     
//16 символов - максимальная длина переводимой строки,   
//поэтому длинные строки разбиваем   
        ph:=pchar(copy(s,16*i+1,16));   
        if AnsiToOem_ then AnsiToOem(ph,ph)   
                      else OemToAnsi(ph,ph);   
        result:=result+ph;   
    end;   
end;
2 способ
Код:
Memo1.Lines.LoadFromFile('file.txt');
Memo1.Font.Charset:=OEM_CHARSET; //866
Memo1.Font.Charset:=DEFAULT_CHARSET; //1251
eoln вне форума Ответить с цитированием
Старый 08.07.2008, 13:16   #5
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Цитата:
Сообщение от eoln Посмотреть сообщение
16 символов - максимальная длина переводимой строки,
Это откуда взялось?! Длина может быть любая.
Код:
function Conv(const s:String; ToOem:Boolean):String;
begin
SetLength(Result,Length(s));
if ToOem then AnsiToOem(PChar(s),PPChar(@Result)^)
         else OemToAnsi(PChar(s),PPChar(@Result)^);
end;

Последний раз редактировалось Somebody; 08.07.2008 в 13:23.
Somebody вне форума Ответить с цитированием
Ответ


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

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Кодировка Nixtone Помощь студентам 4 27.05.2008 14:12
UTF-8 кодировка OrdJONY Общие вопросы Delphi 2 23.03.2008 16:56
Кодировка Dbf Nikolaeva БД в Delphi 7 05.02.2008 13:24
Кодировка satana Общие вопросы Delphi 1 20.12.2007 02:53