- Перекодирование Utf-8 в windows-1251
- Delphi , Синтаксис , Кодировки
- Перекодирование Utf-8 в windows-1251
- Convert text from UTF-8 to Windows 1251
- 2 Answers 2
- Преобразовать текст из кодировки Win1251 в DOS-866
- 3 варианта работы с кодировками веб-страниц в Delphi.
- 1. Delphi и Unicode
- 2. Подготовка исходных данных для работы
- 3. Массив байтов – в нормальный текст
- 3.1. Работа с TEncoding
- 3.2. Использование возможностей MLang для работы с кодовыми страницами
Перекодирование Utf-8 в windows-1251
Delphi , Синтаксис , Кодировки
Перекодирование Utf-8 в windows-1251
Данная функция будет полезна в случае если, по тем или иным причинам, нельзя применять, стандартную функцию UTF8Decode, например если программа будет запускаться под wine в UNIX-подобных системах.
Utf2WinTable : array [0..65, 0..1] of string = (
(#208#144,#192), (#208#145,#193), (#208#146,#194),
(#208#147,#195), (#208#148,#196), (#208#149,#197),
(#208#129,#168), (#208#150,#198), (#208#151,#199),
(#208#152,#200), (#208#153,#201), (#208#154,#202),
(#208#155,#203), (#208#156,#204), (#208#157,#205),
(#208#158,#206), (#208#159,#207), (#208#160,#208),
(#208#161,#209), (#208#162,#210), (#208#163,#211),
(#208#164,#212), (#208#165,#213), (#208#166,#214),
(#208#167,#215), (#208#168,#216), (#208#169,#217),
(#208#170,#218), (#208#171,#219), (#208#172,#220),
(#208#173,#221), (#208#174,#222), (#208#175,#223),
(#208#176,#224), (#208#177,#225), (#208#178,#226),
(#208#179,#227), (#208#180,#228), (#208#181,#229),
(#209#145,#184), (#208#182,#230), (#208#183,#231),
(#208#184,#232), (#208#185,#233), (#208#186,#234),
(#208#187,#235), (#208#188,#236), (#208#189,#237),
(#208#190,#238), (#208#191,#239), (#209#128,#240),
(#209#129,#241), (#209#130,#242), (#209#131,#243),
(#209#132,#244), (#209#133,#245), (#209#134,#246),
(#209#135,#247), (#209#136,#248), (#209#137,#249),
(#209#138,#250), (#209#139,#251), (#209#140,#252),
(#209#141,#253), (#209#142,#254), (#209#143,#255) );
function Utf8ToWin(s : string) : string;
var i : integer;
res :string;
begin
res:=s;
for I := 0 to 65 do
if pos(Utf2WinTable[i,0],res)>0
then res := StringReplace(res, Utf2WinTable[i,0], Utf2WinTable[i,1], [rfReplaceAll]);
Статья Перекодирование Utf-8 в windows-1251 раздела Синтаксис Кодировки может быть полезна для разработчиков на Delphi и FreePascal.
Convert text from UTF-8 to Windows 1251
I try to convert text in utf8 to windows1251.
This is source text Ñàíêò-Ïåòåðáóðã This is targer Санкт-Петербург
I tested a lot of functions: Utf8ToAnsi, UTF8ToString, Utf8Encode and other but didn’t get true result.
2 Answers 2
Let’s try to guess what you are asking. Look at the first five characters:
If we assume that they are in fact from 8 bit Windows code page 1252 then in hex they are encoded like this:
Now, those five bytes when interpreted as 8 bit Windows code page 1251 are:
So it seems that there is no UTF-8 involved here. You are simply misinterpreting text as being from code page 1252 when in fact it is from 1251.
I tested a lot of functions: Utf8ToAnsi, UTF8ToString, Utf8Encode and other but didn’t get true result.
As a more general point, when you find yourself calling functions at random, usually that means that you don’t yet fully understand the problem. It’s a useful skill to be able to recognise that feeling, and know that it is time to step back and attempt to gain a deeper understanding.
There’s not much point in anybody explaining how to convert from UTF-8 to 1251 since that’s not what you need to do. I’m not going to try to show you any code to solve your problem because I don’t know:
- Where the data comes from, or
- What form you need the data to be subsequently transformed into.
Most likely you have read these bytes into an AnsiString with code page 1252. But at this point I judge the guesswork to be a step too far. If you add some clarification to your question then we might be able to add more detail.
I try to convert text in utf8 to windows1251.
Since you are using Delphi 2009+, the easiest solution is to use the UT8String and AnsiString(N) types and let the RTL handle the conversion for you (unless you are compiling for mobile platforms, in which case UTF8String and AnsiString(N) are not available without installing a third party compiler patch):
Alternatively, you can use the RTL’s UnicodeFromLocaleChars() and LocaleCharsFromUnicode() functions:
Or you can use the Win32 MultiByteToWideChar() and WideCharToMultiByte() functions directly (or a third-party Unicode library, such as iconv or ICU):
This is source text Ñàíêò-Ïåòåðáóðã This is targer Санкт-Петербург
Ñàíêò-Ïåòåðáóðã is not the UTF-8 encoded form of Санкт-Петербург , the correct UTF-8 encoded form would be Санкт-Петербург instead. So, as other people have pointed out, your data is not actually encoded in UTF-8 to begin with.
I tested a lot of functions: Utf8ToAnsi, UTF8ToString, Utf8Encode and other but didn’t get true result.
Utf8ToAnsi() does not allow you to specify the target charset. In Delphi 2009+, it decodes a UTF-8 string to a UTF-16 UnicodeString . In pre-2009 versions, it decodes to an AnsiString that is encoded using the OS default Ansi codepage, whatever that happens to be.
UTF8ToString() decodes a UTF-8 string to a UTF-16 UnicodeString .
Utf8Encode() encodes a UTF-16 WideString / UnicodeString to UTF-8.
Преобразовать текст из кодировки Win1251 в DOS-866
С помощью этого кода приложение на этапе создания формы, в данном случае, что очевидно, создает bat файл и записывает в него следующие строки:
Перекодировать введенный текст из кодировки cp866 в win1251
Как перекодировать введенный текст из кодировки cp866 в win1251? Какие функции есть? Мои идея.
Кодировки win1251-UTF8
Подскажите как осуществить сиё действие? К примеру имею $mytext=’Яндекс ‘; //Яндекс зы.
Перевод кодировки в Win1251/UTF8
Вместо русского «Яндекс» пишутся такие кракозябры «Ð¯Ð½Ð´ÐµÐºÑ» как поменять.
Насколько же все это проще в Паскале, где нет ничего кроме своего мозга
В результате Еррор: incompatible types: ‘String’ and ‘PAnsiChar’
Что я делаю не так?
Добавлено через 57 минут
Я также пробовал играть преобразованием переменных, сводить их к одному виду и тогда сообщение Not enough actual parameters. То есть я не могу победить. Спасите, помогите.
данная функция отрабатывает, но возвращает неверный результат: К примеру запись WinToDos(‘»Э»‘) вернет «ж» в кодировке OEM866
Я уже замучался гуглить, если честно, чтобы решить такую банальную проблему, превратить русский текст из Delphi 2010 в русский текст в кодировке OEM866
makc9I, начиная с Delphi 2009 проблема перевода кодировок решается вот так:
функция отработала, но теперь получаю null на выходе при попытке перевести любой символ, если просматривать в notepad++
Добавлено через 5 минут
UI, спасибо, буду пробовать ваш метод, если другого решения не найду.
Просто я уже написал код со старым добрым AssignFile, writeln, присвоил куче переменных данные, предварительно их обработав функцией перевода(неработающей) в кодировку OEM866, гораздо проще было бы найти рабочую функцию, конечно. Но если не найду, буду переписывать код, что ж делать.
Добавлено через 12 минут
Это тебе не Паскаль.
Добрый день, может я не внимательно прочитал или не так понял. Вы хотите чтобы код в созданном Бат файле работал в с директориями, в которых встречаются русские символы?
К примеру при выполнении батника:
del C:\folder\project\project1.exe — работает
,а
del C:\folder\Мои программы\project1.exe — НЕ работает
я правильно понял?
потом еще дополнительно прогонял через StrOemToAnsi
Но закоментировав все эти действия, пришел к выводу, что это все уже и не нужно, в файл все стало писаться как надо.
Добавлено через 43 минуты
поторопился я с выводами, не в тот файл посмотрел, все же надо проделать все процедуры, описанные выше. Но результата добился, спасибо
Да — Query.FieldByName(‘C’).AsAnsiString вернёт данные из DBF «как есть» — т. е., это будут строки однобайтных символов в кодировке CP866. Чтобы получить Windows ANSI кодировку (ANSI RU — CP1251), надо выполнить преобразование CP866 -> CP1251 через StrOemToAnsi(), например.
Кстати, при показе данных через DBGrid, кодировки автоматически преобразуются и в DBGrid тексты верно показываются. Но если строки читаются из набора данных через свойство AsAnsiString — то мы уже получаем данные, как уже говорилось, в том виде, в каком они присутствуют в БД.
Добавлено через 1 час 40 минут
Ralik,
Преобразование из одного кода в другой элементарно сделать и самому.
Для этого зайдите в википедею и выдерите таблицу с кодировками.
На основе этого составьте массив. В нём всего то 256 элементов.
Индекс массива — код в Win1251 содержимое — код DOS-866
А далее дело техники Пишем элементарную функцию
Предположим у вас массив Сod
И. читаем символ из строки SS
Вот и всё. В одну строчку
Сделайте массив двухмерным и добавьте коды Win1251 где индексы — код DOS-866 И вы сможете делать обратное преобразование.
Можете даже написать функцию и при этом сократить массив. учитывая что вся котовасия начинается после индекса 127
Если больше 127 то делаем преобразование, иначе игнорируем.
Вот так — одна — три строчки кода и всё преобразование.
Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь или здесь.
Изменение кодировки Win1251 в UTF8 (необычный случай)
Всем привет! . обычно кодировка проблем не доставляла, а вот недавно столкнулся с проблемой.
DOS-866 в Unicode (UTF-8)
Замаялся с кодировками. в файле данные в Unicode (UTF-8) у меня в консольнмо приложении в DOS-866.
866-MS-DOS to 1251-MS-Windows
«Программа предназначена для перекодировки текстовых файлов из формата кодовой таблицы 866-MS-DOS в.
В чём отличия кодировки ms dos от кодировки ms windows?
Всем привет, подскажите в чём отличия кодировки ms dos от кодировки ms windows?
Проблема с текстовым файлом (DOS 866)
Я собираю строку текстового файла и формирую ее согласно ниже приведенной декларации. .
Драйвер перекодировки символов в тексте таблицы win-1251 в dos-866
Вот есть тз : Legasy драйвер для ОС win NT. входной и выходной текст передается х драйвера с.
3 варианта работы с кодировками веб-страниц в Delphi.
Сколько постов написано в блогах, сколько вопросов задано на форумах о кодировках и ещё большее количество подобных вопросов осталось не отвеченными или ответом было что-то наподобие “Поиском пользовались?” или “Сто раз обсуждалось. ”. Честно говоря, никогда не понимал таких “ответчиков”, ИМХО не хочешь отвечать – лучше жуй и молчи, ответят те, кто захочет.
Понятное дело, что обучать иногда приходится не только с помощью пряника, но и с помощью кнута, но, раз уж такие вопросы всё время всплывают, следовательно они остаются актуальными.
Сегодня я попробую рассказать Вам всё, что мне известно о работе с кодировками в тексте. Вполне возможно, что эта статья поможет Вам при разработке своих проектов в Delphi да и у меня уже пару раз возникало желание немного систематизировать ту информацию. которая накопилась за время существования блога.
1. Delphi и Unicode
Если говорить о работе с Unicode в Delphi, то начать стоит с того, что полноценная поддержка unicode в Delphi стала возможна лишь после выхода Delphi 2009. Такое событие не могло пройти незамеченным, так как благодаря поддержке Unicode и, соответственно, для облегчения работы с кодировками текста в Delphi были реализованы новые возможности, методы, типы данных, о которых написано большое количество статей. На мой взгляд одной из лучших публикаций на эту темя является цикл из трех статей “Delphi и кодировка Unicode” где достаточно чётко и доступно рассказано о нововведениях Delphi 2009 для работы с unicod’ом. Думаю, что нет смысла подробно останавливаться на всех новшествах при наличии ссылки на целых три статьи на эту тему. Остается только упомянуть о том, с чем мы сегодня будем работать для представления веб-страницы в нормальном читаемом виде.
Для первого способа работы с кодировкой мы воспользуемся:
- Класс TEncoding, который и дает нам возможность без лишних хлопот работать с кодировками
- Тип данных TBytes – массива байтов строк
- RawByteString – тип для передачи строковых данных для любой кодовой страницы без каких-либо преобразований последней
В одной из статей блога рассматривалась работа с MLang и сегодня, в качестве второго способа, я продемонстрирую Вам пример её применения при работе с кодировками.
Ну и в качестве третьего способа работы с кодировками, воспользуемся “штатными” методами модуля system. Все три варианта работы с кодировками приведут к одному и тому же результату – текст веб-страницы будет читаемым, без “кракозябров” и вопросительных знаков. Какой способ лучше – решать только Вам.
2. Подготовка исходных данных для работы
Прежде, чем начать что-то кодировать и перекодировать, необходимо это “что-то” получить. В нашем случае – текст веб-страницы. Чтобы не залезать слишком глубоко в вопросы, касающиеся новых типов данных будем сохранять все данные из Сети не в строки или TStringList’ы, как мы к этому привыкли, а воспользуемся типом TBytes.
Используя Synapse исходник любой страницы можно получить, например так:
Теперь, получив данные (свойство Document:TMemoryStream) скопируем эти данные в массив байтов строки TBytes, например так (способ достаточно медленный, приведен исключительно для примера):
Первый этап подготовки можно считать законченным – у нас есть массив байтов строки, которые необходимо представить в виде текста в правильной кодировке. А как узнать, что наш массив TBytes надо перевести в новую “правильную” кодировку? Естественно узнать в какой кодировке была исходная страница. Здесь можно пойти двумя путями:
1. Узнать кодировку из мета-тегов. Обычно кодировка страницы описывается мета-тегом следующего содержания:
. Пример того как узнать кодировку из мета-тегов страницы Вы можете посмотреть в модуле HtmlCPConvert, который я выкладывал в блоге, когда рассматривал работу с MLang.
2. Узнать кодировку текста из заголовков сервера. Если рассматривать этот пример, используя для работу с HTTP
Так как в заголовке может отсутствовать сведения о кодировке, то переменная DefCharset должна содержать имя какой-либо дефолтной кодовой страницы, например windows-1251.
Теперь у нас есть все исходные данные:
1. Массив байтов строки B:TBytes;
2. Сведения о кодировке.
Приступим к преобразованию байтов в читабельный текст.
3. Массив байтов – в нормальный текст
3.1. Работа с TEncoding
Разработчики Delphi предусмотрели использование двух взаимопротивоположных метода:
- function BytesOf(const Val: RawByteString): TBytes; – получение байтов из строки
- function StringOf(const Bytes: TBytes): UnicodeString; – получение строки из массива байтов
Пусть Вас не пугает то, что StringOf возвращает UnicodeString, т.к., начиная с Delphi 2009
Теперь, что касается непосредственно работы с TEncoding. Во-первых, от нас не требуется создавать отдельный экземпляр класса, наподобие такого:
Во-вторых, с помощью TEncoding мы можем менять кодовую страницу не преобразовывая массив байтов в строку. Для этого класс содержит следующие классовые методы:
Одним из этих методов мы и воспользуемся. Для того, чтобы продемонстрировать работу с TEncoding попробуем получить текст прямо из этого блога. Кодировка UTF-8, именно она наиболее часто является “проблемной” и возвращает в TMemo или ещё куда-либо “кракозябры”.
Создадим простое приложение как показано на рисунке:
В ComboBox сразу занесем все варианты работы с текстом:
- Без преобразования
- TEncoding (модуль SysUtils)
- MLang
- Utf8ToAnsi (модуль System)
По нажатию кнопки TButton будем грузить страницу в массив байтов и, зависимости от выбранного варианта работы с текстом, преобразовывать массив в строку и выводить в Memo. Для первого варианта (без преобразования) код может быть следующий:
Запускаем приложение и видим:
Как и ожидалось – вместо русских букв кракозябры. Преобразуем их с помощью классового метода TEncoding.Convert:
Здесь следует отметить, что TEncoding.GetEncoding(1251) возвращает кодовую страницу кириллического текста. Если необходимо получить другую кодовую страницу, то можете либо воспользоваться классовыми свойствами TEncoding либо определить кодовую страницу как я, используя данные с MSDN о доступных в Windows кодовых страницах.
Проверим, что получилось в итоге. Грузим ту же самую страницу:
Как видите – кракозябры преобразовались в нормальный русский текст.
Какие плюсы дает нам использование TEncoding? Думаю, что ответ вполне очевиден – у нас появляется под рукой инструмент, позволяющий перекодировать строки из любых кодировок в любые, т.е. фактически возможности работы с текстом ограничиваются количеством доступных в Windows кодовых страниц, а их по данным MSDN 152 штуки. Прикиньте сколько вариантов получится, если в Convert используется пара кодовых страниц. Много :).
Но, наряду с таким большим и жирным плюсом существует и минус – TEncoding есть только в версиях Delphi 2009 и выше, что исключает его использование в более ранних версиях. Как быть?
Если хотите получить не менее впечатляющие возможности работы с кодировками – используйте возможности MLang. Вот как раз и пример его использования.
3.2. Использование возможностей MLang для работы с кодовыми страницами
Позволю себе ещё раз напомнить, что скачать всё необходимое для реализации возможностей MLang Вы можете с этой страницы или, перейдя по этой ссылке. В архиве содержатся всего два модуля: MLang.pas и HtmlCPConvert.pas. Подключаем оба модуля к проекту и для получения читабельного текста пишем:
RawHTMLToHTML из модуля HtmlCPConvert переводит текст в кодировку windows-1251. Также есть и обратный метод для перевода текста в RawByteString и называется этот метод HTMLToRawHTML.
Результат преобразования текста с помощью MLang абсолютно идентичен предыдущему варианту:
Если Вам необходимо работать со множеством кодировок, как при использовании TEncoding, то придётся самостоятельно немного доработать модуль HtmlCPConvert. В целом возможности TEncoding и MLang вполне сопоставимы.
И, наконец, третий вариант – использование методов модуля System.pas.