Delphi перекодировка utf 8 в 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 di...

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):

type
  Win1251String = type AnsiString(1251);
var
  Utf8: UTF8String;
  Win1251: Win1251String;
begin
  // populate UTF-8 as needed...
  Utf8 := ...;

  // converts from UTF-8 to UTF-16 to Windows-1251...
  Win1251 := Win1251String(Utf8);

  // use Win1251 as needed...
end;

Alternatively, you can use the RTL’s UnicodeFromLocaleChars() and LocaleCharsFromUnicode() functions:

var
  Utf8: UTF8String;
  Utf16: UnicodeString;
  Win1251: RawByteString;
begin
  // populate UTF-8 as needed...
  Utf8 := ...;

  // convert from UTF-8 to UTF-16...
  SetLength(Utf16, UnicodeFromLocaleChars(65001, 0, PAnsiChar(UTf8), Length(Utf8), nil, 0));
  UnicodeFromLocaleChars(65001, 0, PAnsiChar(Utf8), Length(Utf8), PWideChar(Utf16), Length(Utf16));

  // convert from UTF-16 to Windows-1251...
  SetLength(Win1251, LocaleCharsFromUnicode(1251, 0, PWideChar(Utf16), Length(Utf16), nil, 0, nil, nil));
  LocaleCharsFromUnicode(1251, 0, PWideChar(Utf16), Length(Utf16), PAnsiChar(Win1251), Length(Win1251), nil, nil);
  SetCodePage(Win1251, 1251);

  // use Win1251 as needed...
end;

Or you can use the Win32 MultiByteToWideChar() and WideCharToMultiByte() functions directly (or a third-party Unicode library, such as iconv or ICU):

var
  Utf8: UTF8String;
  Utf16: UnicodeString; // or WideString in pre-2009 versions
  Win1251: AnsiString;
begin
  // populate UTF-8 as needed...
  Utf8 := ...;

  // convert from UTF-8 to UTF-16...
  SetLength(Utf16, MultiByteToWideChar(65001, 0, PAnsiChar(UTf8), Length(Utf8), nil, 0));
  MultiByteToWideChar(65001, 0, PAnsiChar(Utf8), Length(Utf8), PWideChar(Utf16), Length(Utf16));

  // convert from UTF-16 to Windows-1251...
  SetLength(Win1251, WideCharToMultiByte(1251, 0, PWideChar(Utf16), Length(Utf16), nil, 0, nil, nil));
  WideCharToMultiByte(1251, 0, PWideChar(Utf16), Length(Utf16), PAnsiChar(Win1251), Length(Win1251), nil, nil);

  // use Win1251 as needed...
end;

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.

уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Сколько постов написано в блогах, сколько вопросов задано на форумах о кодировках и ещё большее количество подобных вопросов осталось не отвеченными или ответом было что-то наподобие «Поиском пользовались?» или «Сто раз обсуждалось!!!». Честно говоря, никогда не понимал таких «ответчиков», ИМХО не хочешь отвечать — лучше жуй и молчи, ответят те, кто захочет.
Понятное дело, что обучать иногда приходится не только с помощью пряника, но и с помощью кнута, но, раз уж такие вопросы всё время всплывают, следовательно они остаются актуальными.
Сегодня я попробую рассказать Вам всё, что мне известно о работе с кодировками в тексте. Вполне возможно, что эта статья поможет Вам при разработке своих проектов в Delphi да и у меня уже пару раз возникало желание немного систематизировать ту информацию. которая накопилась за время существования блога.

1. Delphi и Unicode

Если говорить о работе с Unicode в Delphi, то начать стоит с того, что полноценная поддержка unicode в Delphi стала возможна лишь после выхода Delphi 2009. Такое событие не могло пройти незамеченным, так как благодаря поддержке Unicode и, соответственно, для облегчения работы с кодировками текста в Delphi были реализованы новые возможности, методы, типы данных, о которых написано большое количество статей. На мой взгляд одной из лучших публикаций на эту темя является цикл из трех статей «Delphi и кодировка Unicode» где достаточно чётко и доступно рассказано о нововведениях Delphi 2009 для работы с unicod’ом. Думаю, что нет смысла подробно останавливаться на всех новшествах при наличии ссылки на целых три статьи на эту тему. Остается только упомянуть о том, с чем мы сегодня будем работать для представления веб-страницы в нормальном читаемом виде.
Для первого способа работы с кодировкой мы воспользуемся:

  1. Класс TEncoding, который и дает нам возможность без лишних хлопот работать с кодировками
  2. Тип данных TBytes — массива байтов строк
  3. RawByteString — тип для передачи строковых данных для любой кодовой страницы без каких-либо преобразований последней

В одной из статей блога рассматривалась работа с MLang и сегодня, в качестве второго способа, я продемонстрирую Вам пример её применения при работе с кодировками.
Ну и в качестве третьего способа работы с кодировками, воспользуемся «штатными» методами модуля system. Все три варианта работы с кодировками приведут к одному и тому же результату — текст веб-страницы будет читаемым, без «кракозябров» и вопросительных знаков. Какой способ лучше — решать только Вам.

2. Подготовка исходных данных для работы

Прежде, чем начать что-то кодировать и перекодировать, необходимо это «что-то» получить. В нашем случае — текст веб-страницы. Чтобы не залезать слишком глубоко в вопросы, касающиеся новых типов данных будем сохранять все данные из Сети не в строки или TStringList’ы, как мы к этому привыкли, а воспользуемся типом TBytes.
Используя Synapse исходник любой страницы можно получить, например так:

  with THTTPSend.Create do
    begin
      if HTTPMethod('GET',URL)then
        begin
           //в свойстве Document объекта THTTPSend содержится исходник страницы
           //обрабатываем Document 
        end;
    end;

Теперь, получив данные (свойство Document:TMemoryStream) скопируем эти данные в массив байтов строки TBytes, например так (способ достаточно медленный, приведен исключительно для примера):

var B: TBytes;
     i:integer;
begin
//загружаем контент страницы
  with THTTPSend.Create do
    begin
      if HTTPMethod('GET',URL) then
        begin
          Document.Position:=0;
          SetLength(B,Document.Size);
          for i := 0 to Document.Size - 1 do
            Document.Read(B[i],1);
        end;
    end;

Первый этап подготовки можно считать законченным — у нас есть массив байтов строки, которые необходимо представить в виде текста в правильной кодировке. А как узнать, что наш массив TBytes надо перевести в новую «правильную» кодировку? Естественно узнать в какой кодировке была исходная страница. Здесь можно пойти двумя путями:
1. Узнать кодировку из мета-тегов. Обычно кодировка страницы описывается мета-тегом следующего содержания:

META http-equiv="content-type" content="text/html; charset=windows-1251

. Пример того как узнать кодировку из мета-тегов страницы Вы можете посмотреть в модуле HtmlCPConvert, который я выкладывал в блоге, когда рассматривал работу с MLang.
2. Узнать кодировку текста из заголовков сервера. Если рассматривать этот пример, используя для работу с HTTP-протоколом библиотеку Synapse, то заголовки сервера будут содержаться в свойстве Headers:TStringList. Найти элемент, содержащий сведения о кодировке и получить имя кодовой страницы можно, например так:

function GetCharset(Headers: TStringList): string;
var i:integer;
begin
  if Headers.Count=0 then Exit;
  for I := 0 to Headers.Count - 1 do
    begin
      //Content-Type: text/html; charset=UTF-8
      if Pos('content-type',LowerCase(Headers[i]))>0 then
        if pos('=',Headers[i])>0 then
          Result:=LowerCase(Copy(Headers[i],pos('=',Headers[i])+1,Length(Headers[i])-pos('=',Headers[i])))
        else
          Result:=DefCharset;
    end;
end;

Так как в заголовке может отсутствовать сведения о кодировке, то переменная DefCharset должна содержать имя какой-либо дефолтной кодовой страницы, например windows-1251.
Теперь у нас есть все исходные данные:
1. Массив байтов строки B:TBytes;
2. Сведения о кодировке.
Приступим к преобразованию байтов в читабельный текст.

3. Массив байтов — в нормальный текст

3.1. Работа с TEncoding

Разработчики Delphi предусмотрели использование двух взаимопротивоположных метода:

  1. function BytesOf(const Val: RawByteString): TBytes; — получение байтов из строки
  2. function StringOf(const Bytes: TBytes): UnicodeString; — получение строки из массива байтов

Пусть Вас не пугает то, что StringOf возвращает UnicodeString, т.к., начиная с Delphi 2009

type
  UnicodeString = string

Теперь, что касается непосредственно работы с TEncoding. Во-первых, от нас не требуется создавать отдельный экземпляр класса, наподобие такого:

var Enc: TEncoding;
begin
  Enc:=TEncoding.Create;
end;

Во-вторых, с помощью TEncoding мы можем менять кодовую страницу не преобразовывая массив байтов в строку. Для этого класс содержит следующие классовые методы:

class function Convert(Source, Destination: TEncoding; Bytes: TBytes): TBytes; overload;
    class function Convert(Source, Destination: TEncoding; Bytes: TBytes; StartIndex, Count: Integer): TBytes; overload;

Одним из этих методов мы и воспользуемся. Для того, чтобы продемонстрировать работу с TEncoding попробуем получить текст прямо из этого блога. Кодировка UTF-8, именно она наиболее часто является «проблемной» и возвращает в TMemo или ещё куда-либо «кракозябры».
Создадим простое приложение как показано на рисунке:

В ComboBox сразу занесем все варианты работы с текстом:

  1. Без преобразования
  2. TEncoding (модуль SysUtils)
  3. MLang
  4. Utf8ToAnsi (модуль System)

По нажатию кнопки TButton будем грузить страницу в массив байтов и, зависимости от выбранного варианта работы с текстом, преобразовывать массив в строку и выводить в Memo. Для первого варианта (без преобразования) код может быть следующий:

with THTTPSend.Create do
    begin
      if HTTPMethod('GET',Edit1.Text)then
        begin
          Document.Position:=0;
          SetLength(B,Document.Size);
          for i := 0 to Document.Size - 1 do
            Document.Read(B[i],1);
          label4.Caption:=GetCharset(Headers);
        end;
    end;
Label6.Caption:=IntToStr(Length(B))+' байт текста';
case ComboBox1.ItemIndex of
 0:Memo1.Text:=StringOf(B);
[...]
end;

Запускаем приложение и видим:

Как и ожидалось — вместо русских букв кракозябры. Преобразуем их с помощью классового метода TEncoding.Convert:

var astr: String;
     B: TBytes;
[...]
case ComboBox1.ItemIndex of
 0:Memo1.Text:=StringOf(B);
 1:begin
     B:=TEncoding.Convert(TEncoding.UTF8,TEncoding.GetEncoding(1251),B);
     astr:=StringOf(B);
     Memo1.Lines.Add(astr);
   end;
[...]
end;

Здесь следует отметить, что TEncoding.GetEncoding(1251) возвращает кодовую страницу кириллического текста. Если необходимо получить другую кодовую страницу, то можете либо воспользоваться классовыми свойствами TEncoding либо определить кодовую страницу как я, используя данные с MSDN о доступных в Windows кодовых страницах.
Проверим, что получилось в итоге. Грузим ту же самую страницу:

Как видите — кракозябры преобразовались в нормальный русский текст.
Какие плюсы дает нам использование TEncoding? Думаю, что ответ вполне очевиден — у нас появляется под рукой инструмент, позволяющий перекодировать строки из любых кодировок в любые, т.е. фактически возможности работы с текстом ограничиваются количеством доступных в Windows кодовых страниц, а их по данным MSDN 152 штуки. Прикиньте сколько вариантов получится, если в Convert используется пара кодовых страниц. Много :).
Но, наряду с таким большим и жирным плюсом существует и минус — TEncoding есть только в версиях Delphi 2009 и выше, что исключает его использование в более ранних версиях. Как быть?
Если хотите получить не менее впечатляющие возможности работы с кодировками — используйте возможности MLang. Вот как раз и пример его использования.

3.2. Использование возможностей MLang для работы с кодовыми страницами

Позволю себе ещё раз напомнить, что скачать всё необходимое для реализации возможностей MLang Вы можете с этой страницы или, перейдя по этой ссылке. В архиве содержатся всего два модуля: MLang.pas и HtmlCPConvert.pas. Подключаем оба модуля к проекту и для получения читабельного текста пишем:

Memo1.Text:=RawHTMLToHTML(StringOf(B));

RawHTMLToHTML из модуля HtmlCPConvert переводит текст в кодировку windows-1251. Также есть и обратный метод для перевода текста в RawByteString и называется этот метод HTMLToRawHTML.
Результат преобразования текста с помощью MLang абсолютно идентичен предыдущему варианту:

Если Вам необходимо работать со множеством кодировок, как при использовании TEncoding, то придётся самостоятельно немного доработать модуль HtmlCPConvert. В целом возможности TEncoding и MLang вполне сопоставимы.
И, наконец, третий вариант — использование методов модуля System.pas.

3.3. Использование методов System.pas для перекодирования текста

В модуле System.pas можно найти следующие полезные функции для работы с кодировками:

Utf8Encode(const US: UnicodeString): RawByteString;
function UTF8EncodeToShortString(const WS: WideString): ShortString;
function Utf8Decode(const S: RawByteString): WideString;
function UTF8ToUnicodeString(const S: RawByteString): UnicodeString;
function UTF8ToString(const S: RawByteString): string;
function AnsiToUtf8(const S: string): RawByteString;
function Utf8ToAnsi(const S: RawByteString): string;

Как видите, методы завязаны на работе с конкретными кодовыми страницами UTF-8, ANSI, а также на работе с новым типом данных RawByteString. Поэтому возможности третьего способы по сравнению с первыми двумя резко ограничены. Хотя в реалиях нынешнего Рунета их вполне достаточно, т.к. веб-страницы в кодировке koi8-r уже больше раритет, чем обыденность. Использовать методы достаточно просто. Например так:

var RS: RawByteString;
[...]
begin
   RS:=StringOf(B);
   Memo1.Text:=Utf8ToAnsi(RS);
end;

я перевел массив байтов в стоку RawByteString и затем представил её в кодировке Ansi, получив в Memo читабельный русский текст.
Вот три способа работы с различными кодировками текста, которые могут применяться где угодно. И это только часть всех возможностей, которые предоставляет нам Delphi. Какой способ использовать — решать Вам.
Кстати, при работе с кодировками следует обратить внимание на то, что «кракозябры» в тексте — это следствие представления строки с использованием неправильной кодовый страницы. Если же вместо русских букв появляются знаки вопроса, то это следствие того, что в текущей кодовой странице текста нет тех символов, которые вы пробуете показать. Например, представляя текст ANSI в кодировке UTF-8 мы получаем кракозябры, а если попробовать представить текст ANSI Cyrillic (windows-1251) с кодовой страницей ANSI Latin 1 (windows-1252), то вместо русских букв получим знаки вопроса, т.к. в windows-1252 отсутствуют русские буквы и т.д.

уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

 
Zhachuk ©
 
(2005-06-08 11:14)
[0]

Имеется проблема: необходимо перекодировать строку в кодировке UTF-8 в Windows-1251 средствами Delphi-4. В Delphi-6 есть функция Utf8ToAnsi, которая и делает все дело, однако в Delphi-4 ее нет. В результате долгих поисков в Интернете нарыл бесплатную библиотеку DIConverters.pas (http://www.zeitungsjunge.de/delphi/converters/index.htm), которая вроде как позволяет конвертировать из UTF-8 в Unicode. Однако умения воспользоваться этой библиотекой не хватает :)
Если у кого есть мысли, как выполнить перекодировку UTF-8 —> Unicode —> Windows-1251, please, чиркните примерчик.


 
dmitry501 ©
 
(2005-06-08 11:32)
[1]

Zhachuk ©   (08.06.05 11:14)
Вот, взял из  Audio Tools Library (Freeware) http://jfaul.de/atl

UTF-ANSI
function ConvertFromUTF8(const Source: string): string;
var
 Iterator, SourceLength, FChar, NChar: Integer;
begin
 { Convert UTF-8 string to ANSI string }
 Result := "";
 Iterator := 0;
 SourceLength := Length(Source);
 while Iterator < SourceLength do
 begin
   Inc(Iterator);
   FChar := Ord(Source[Iterator]);
   if FChar >= $80 then
   begin
     Inc(Iterator);
     if Iterator > SourceLength then break;
     FChar := FChar and $3F;
     if (FChar and $20) <> 0 then
     begin
       FChar := FChar and $1F;
       NChar := Ord(Source[Iterator]);
       if (NChar and $C0) <> $80 then  break;
       FChar := (FChar shl 6) or (NChar and $3F);
       Inc(Iterator);
       if Iterator > SourceLength then break;
     end;
     NChar := Ord(Source[Iterator]);
     if (NChar and $C0) <> $80 then break;
     Result := Result + WideChar((FChar shl 6) or (NChar and $3F));
   end
   else
     Result := Result + WideChar(FChar);
 end;
end;

UTF-UNICODE

function DecodeUTF8(const Source: string): WideString;
var
 Index, SourceLength, FChar, NChar: Cardinal;
begin
 { Convert UTF-8 to unicode }
 Result := "";
 Index := 0;
 SourceLength := Length(Source);
 while Index < SourceLength do
 begin
   Inc(Index);
   FChar := Ord(Source[Index]);
   if FChar >= $80 then
   begin
     Inc(Index);
     if Index > SourceLength then exit;
     FChar := FChar and $3F;
     if (FChar and $20) <> 0 then
     begin
       FChar := FChar and $1F;
       NChar := Ord(Source[Index]);
       if (NChar and $C0) <> $80 then  exit;
       FChar := (FChar shl 6) or (NChar and $3F);
       Inc(Index);
       if Index > SourceLength then exit;
     end;
     NChar := Ord(Source[Index]);
     if (NChar and $C0) <> $80 then exit;
     Result := Result + WideChar((FChar shl 6) or (NChar and $3F));
   end
   else
     Result := Result + WideChar(FChar);
 end;
end;

function EncodeUTF8(const Source: WideString): string;
var
 Index, SourceLength, CChar: Cardinal;
begin
 { Convert unicode to UTF-8 }
 Result := "";
 Index := 0;
 SourceLength := Length(Source);
 while Index < SourceLength do
 begin
   Inc(Index);
   CChar := Cardinal(Source[Index]);
   if CChar <= $7F then
     Result := Result + Source[Index]
   else if CChar > $7FF then
   begin
     Result := Result + Char($E0 or (CChar shr 12));
     Result := Result + Char($80 or ((CChar shr 6) and $3F));
     Result := Result + Char($80 or (CChar and $3F));
   end
   else
   begin
     Result := Result + Char($C0 or (CChar shr 6));
     Result := Result + Char($80 or (CChar and $3F));
   end;
 end;
end;


Пост

Hello :)

Столкнулся с проблемой в Delphi, перекодировкой текста с UTF-8 в Windows-1251, в Delphi нет ICONV, как в PHP, для конвертации текста без проблем, вот нашел Юнит, который решает эту проблему с помощью библиотеки libiconv2.dll

unit iconv;
interface
uses
Windows,Classes,SysUtils;
 
procedure ConvertFiles(const InFileName,OutFileName:string;const FromCP,ToCP:string);
function iconv2(s, FromCP, ToCP: string): string;
 
implementation
 
const
iconv_lib='libiconv2.dll';
type
size_t=Cardinal;
iconv_t=Pointer;
argptr=iconv_t;
 
function errno:PInteger; cdecl;external'msvcrt.dll' Name'_errno';
function iconv_open(tocode:PChar;fromcode:PChar):iconv_t; cdecl;external iconv_lib Name'libiconv_open';
function iconv_convert(cd:iconv_t;var inbuf:Pointer;var inbytesleft:size_t;var outbuf:Pointer;var outbytesleft:size_t):size_t; cdecl;external iconv_lib Name'libiconv';
function iconv_close(cd:iconv_t):Integer; cdecl;external iconv_lib Name'libiconv_close';
function iconvctl(cd:iconv_t;request:Integer;argument:argptr):Integer; cdecl;external iconv_lib Name'libiconvctl';
 
const
E2BIG=7;
EINVAL=22;
EILSEQ=84;
ICONV_TRIVIALP=0;//int *argument
ICONV_GET_TRANSLITERATE=1;//int *argument
ICONV_SET_TRANSLITERATE=2;//const int *argument
ICONV_GET_DISCARD_ILSEQ=3;//Int*argument
ICONV_SET_DISCARD_ILSEQ=4;//const Int*argument
 
procedure ConvertStreams(cd:iconv_t;InStream,OutStream:TStream);
const
BufferSize=4096;
var
inbuf:array[0..BufferSize*2-1] of Char;
insize,inbufsize,inbufrest:DWORD;
inptr:Pointer;
function Convert:Boolean;
var
outbuf:array[0..BufferSize-1] of Char;
outptr:Pointer;
outsize:DWORD;
res:Integer;
begin
Result:=True;
outptr:[email protected];
outsize:=SizeOf(outbuf);
res:=iconv_convert(cd,inptr,insize,outptr,outsize);
if outptr<>@outbuf then
OutStream.WriteBuffer(outbuf,PChar(outptr)[email protected]);
if res=-1 then begin
case errno^ of
EILSEQ:raise Exception.Create('cannot convert');
EINVAL:begin
if (inbufsize=0)or(insize>BufferSize) then
raise Exception.Create('incomplete character or shift sequence')
else begin
inbufrest:=insize;
Move(inptr^,inbuf[BufferSize-insize],insize);
Result:=False;
end;
end;
E2BIG:;
else
raise Exception.Create('unknown error')
end;
end;
end;
begin
inbufrest:=0;
while True do begin
inbufsize:=InStream.Read(inbuf[BufferSize],BufferSize);
if inbufsize=0 then
if inbufrest=0 then begin
inptr:=nil;
Convert;
Exit;
end
else
raise Exception.Create('incomplete character or shift sequence')
else begin
inptr:[email protected][BufferSize-inbufrest];
insize:=inbufrest+inbufsize;
inbufrest:=0;
while (insize>0)and Convert do
;
end;
end;
end;
 
function iconv2(s, FromCP, ToCP: string): string;
var
cd:iconv_t;
Buf:Integer;
InStream,OutStream:TMemoryStream;
begin
Result := s;
cd:=iconv_open(PChar(ToCP),PChar(FromCP));
if cd=iconv_t(-1) then
raise Exception.Create('internal error');
try
Buf:=1;
iconvctl(cd,ICONV_SET_DISCARD_ILSEQ,@Buf);
iconv_convert(cd,Pointer(nil^),size_t(nil^),Pointer(nil^),size_t(nil^));
InStream:=TMemoryStream.Create;
try
OutStream:=TMemoryStream.Create;
try
InStream.Write(s[1], length(s));
InStream.Seek(0, soFromBeginning);
ConvertStreams(cd,InStream,OutStream);
SetLength(s, OutStream.Size);
OutStream.Seek(0, soFromBeginning);
OutStream.Read(s[1], OutStream.Size);
Result := s;
finally
OutStream.Free;
end;
finally
InStream.Free;
end;
finally
iconv_close(cd);
end;
end;
 
procedure ConvertFiles(const InFileName,OutFileName:string;const FromCP,ToCP:string);
var
cd:iconv_t;
Buf:Integer;
InStream,OutStream:TFileStream;
begin
cd:=iconv_open(PChar(ToCP),PChar(FromCP));
if cd=iconv_t(-1) then
raise Exception.Create('internal error');
try
Buf:=1;
iconvctl(cd,ICONV_SET_DISCARD_ILSEQ,@Buf);
iconv_convert(cd,Pointer(nil^),size_t(nil^),Pointer(nil^),size_t(nil^));
InStream:=TFileStream.Create(InFileName,fmOpenRead);
try
OutStream:=TFileStream.Create(OutFileName,fmCreate);
try
ConvertStreams(cd,InStream,OutStream);
finally
OutStream.Free;
end;
finally
InStream.Free;
end;
finally
iconv_close(cd);
end;
end;
 
end.

Здравствуйте!
Как преобразовать строку из UTF-8 в WIN-1251?
И может кто знает ссылочки про эти форматы,
желательно на русском языке.

3 ответа

10

02 июня 2005 года

Freeman

3.2K / / 06.03.2004

Цитата:

Originally posted by senser
Как преобразовать строку из UTF-8 в WIN-1251?
И может кто знает ссылочки про эти форматы,
желательно на русском языке.

Тебе через систему или как? Например, в Дельфи, начиная с шестой версии, есть функции UTF8Encode/Decode. Если через систему, смотри полное описание функции WideCharToMultiByte и другие из этой группы. Ну, а если по каким-то причинам вручную, ищи алгоритмы сам и геморрой тоже самостоятельно имей.

7.0K

02 июня 2005 года

senser

24 / / 22.10.2004

Цитата:

Originally posted by Freeman
Тебе через систему или как? Например, в Дельфи, начиная с шестой версии, есть функции UTF8Encode/Decode. Если через систему, смотри полное описание функции WideCharToMultiByte и другие из этой группы. Ну, а если по каким-то причинам вручную, ищи алгоритмы сам и геморрой тоже самостоятельно имей.

Благодарствую!
P.S. А геморроя мне сейчас и так хватает.

12K

08 июня 2005 года

zhachuk

1 / / 08.06.2005

Существует бесплатная библиотека DIConverters.pas (http://www.zeitungsjunge.de/delphi/converters/index.htm).
Работает под все версии Дельфи, начиная со 2ой. Позволяет конвертировать многие кодировки, в том числе и UTF-8 в Unicode. Однако как ей пользоваться, никак не пойму.

Если кто знает и умеет, напишите, плз, пример, как конвертировать UTF-8—>Unicode—>Windows-1251 (ANSI) используя Delphi 4.

Премного благодарен

Руслан

2009 г.

Delphi и кодировка Unicode

Часть II: Новые функции библиотеки RTL и классы для поддержки кодировки Unicode

Nick Hodges, Embarcadero

Перевод: Виктор Роднев, www.interface.ru

Оригинал: Delphi in a Unicode World Part II: New RTL Features and Classes to Support Unicode

В данной статье рассматриваются новые функции библиотеки Tiburon Runtime Library, которые помогают обрабатывать строки Unicode.

Наверх

Введение

В Части I было показано, какие выгоды дает разработчикам на Delphi поддержка кодировки Unicode, позволяя работать со всеми наборами символов в кодировке Unicode. Были рассмотрены основные особенности типа строки UnicodeString и было показано, как его можно использовать в Delphi.

В части II будет рассказано о некоторых новых функциях библиотеки Delphi Runtime Library, предназначенных для поддержки Unicode, и общих методах обработки строк.

Класс TCharacter

Библиотека Tiburon RTL включает новый класс TCharacter, который описывается в модуле Character. Это закрытый класс, который полностью состоит из статичных функций класса. Разработчикам не следует создавать экземпляры класса TCharacter, предпочтительнее просто вызывать его статические методы класса напрямую. Функции этого класса позволяют, в числе прочего, выполнять:

  • преобразование символов в верхний или нижний регистр;
  • определение типа данного символа, то есть является ли символ буквой, цифрой, знаком препинания и так далее.

Классом TCharacter используются стандарты, установленные организацией Unicode consortium.

Разработчики могут использовать класс TCharacter для выполнения многих действий, выполнявшихся до этого с наборами символов. Например, следующий программный код:

uses
Character;

begin
if MyChar in ["a"..."z", "A"..."Z"] then
begin
  ...
end;
end;
можно легко заменить кодом:
uses
  Character;

begin
if TCharacter.IsLetter(MyChar) then
begin
    ...
end;
end;

Модуль Character содержит также ряд автономных функций, которые выполняют функции каждой из функций класса TCharacter, так что если предпочтительнее простой вызов функции, приведенный выше программный код можно переписать как:

uses
  Character;

begin
if IsLetter(MyChar) then
begin
    ...
end;
end;

Таким образом, класс TCharacter можно использовать для выполнения многих действий или проверки символов, которая может понадобиться.

Кроме того, класс TCharacter содержит методы класса, позволяющие определить, является ли символ верхним или нижним суррогатом суррогатной пары.

Класс TEncoding

Библиотека Tiburon RTL также включает новый класс TEncoding. Его назначение — определить конкретный тип кодировки символов, чтобы можно было сообщить библиотеке VCL, какой тип кодировки необходимо использовать в конкретных ситуациях.

Например, пусть есть экземпляр TStringList, содержащий текст, который необходимо записать в файл. Ранее необходимо было бы написать

begin
  ...
  MyStringList.SaveToFile("SomeFilename.txt"); 
  ...
end;

и файл записался бы, по умолчанию, в кодировке ANSI. Данный код по-прежнему хорошо работает — файл запишется им в кодировке ANSI, как и раньше, но теперь, когда в Delphi поддерживаются строковые данные в кодировке Unicode, разработчикам может потребоваться записать строковые данные в какой-либо конкретной кодировке. Поэтому оператор SaveToFile (а также LoadFromFile) теперь имеет дополнительный второй параметр, которым определяется используемая кодировка:

begin
  ...
  MyStringList.SaveToFile("SomeFilename.txt", TEncoding.Unicode); 
  ...
end;

При выполнении приведенного выше кода файл будет записан как текстовый файл в кодировке Unicode (UTF-16).

Классом TEncoding будет также преобразовываться заданный набор байтов из одной кодировки в другую, извлекаться информация о байтах и/или символах в заданной строке или массиве символов, преобразовываться любая строка в массив array of byte (TBytes) и выполняться другие функции, которые могут потребоваться для конкретной кодировки заданной строки или заданного массива символов.

Класс TEncoding включает следующие свойства класса, дающие доступ к экземпляру TEncoding заданной кодировки:

    class property ASCII: TEncoding read GetASCII;
    class property BigEndianUnicode: TEncoding read GetBigEndianUnicode;
    class property Default: TEncoding read GetDefault;
    class property Unicode: TEncoding read GetUnicode;
    class property UTF7: TEncoding read GetUTF7;
    class property UTF8: TEncoding read GetUTF8;

Свойство Default ссылается на активную кодовую страницу ANSI. Свойство Unicode ссылается на UTF-16.

Класс TEncoding также включает функцию

class function TEncoding.GetEncoding(CodePage: Integer): TEncoding;

которая будет возвращать экземпляр TEncoding, соответствующий кодовой странице, переданной в параметре.

Кроме того, он включает следующую функцию:

function GetPreamble: TBytes;

которая будет возвращать правильный маркер порядка байтов для заданной кодировки.

Класс TEncoding также представляет собой интерфейс, совместимый с классом .Net Encoding.

TStringBuilder

Библиотека RTL теперь включает класс TStringBuilder. Его назначение ясно из его названия — это класс, предназначенный для создания строк. Класс TStringBuilder содержит большое количество перегружаемых функций для добавления, замены и вставки содержимого в заданную строку.  Этот класс упрощает создание единых строк из множества различных типов данных. Каждая из функций Append, Insert и Replace возвращает экземпляр класса TStringBuilder, поэтому их можно легко объединять для создания единой строки.

Например, можно использовать класс TStringBuilder вместо усложненного оператора Format. Например, можно написать следующий программный код:

procedure TForm86.Button2Click(Sender: TObject);
var
  MyStringBuilder: TStringBuilder;
  Price: double;
begin
  MyStringBuilder := TStringBuilder.Create('');
  try
    Price := 1.49;
    Label1.Caption := MyStringBuilder.Append('The apples are $').Append(Price).
             ÄAppend(' a pound.').ToString;
  finally
    MyStringBuilder.Free;
  end;
end;

Класс TStringBuilder также представляет собой интерфейс, совместимый с классом .Net StringBuilder.

Объявление новых типов строк

Компилятор Tiburon позволяет объявить собственный тип строки, связанный с заданной кодовой страницей. Доступно любое число кодовых страниц. Например, если необходим тип строки, соответствующий кодировке ANSI-кириллице, можно объявить:

type
  // Кодовая страница для ANSI-кириллицы - 1251
  CyrillicString = type Ansistring(1251);

И новый тип строки будет соответствовать кодовой странице кириллицы.

Дополнительная поддержка Unicodeбиблиотекой RTL

В библиотеку RTL добавлен ряд подпрограмм, которыми поддерживается использование строк Unicode.

StringElementSize

Подпрограммой StringElementSize возвращается типичный размер элемента (элемента кода) в заданной строке. Рассмотрим следующий код:

procedure TForm88.Button3Click(Sender: TObject);
var
  A: AnsiString;
  U: UnicodeString;
begin
  A := 'This is an AnsiString';
  Memo1.Lines.Add('The ElementSize for an AnsiString is: ' + IntToStr(StringElementSize(A)));
  U := 'This is a UnicodeString';
  Memo1.Lines.Add('The ElementSize for an UnicodeString is: ' + IntToStr(StringElementSize(U)));
end;

Результатом выполнения приведенного выше кода будет:

The ElementSize for an AnsiString is: 1
The ElementSize for an UnicodeString is: 2

StringCodePage

Подпрограммой StringCodePage будет возвращаться значение Word, которое соответствует кодовой странице для заданной строки.

Рассмотрим следующий код:

procedure TForm88.Button2Click(Sender: TObject);
type
  // Кодовая страница для ANSI-кириллицы - 1251
  CyrillicString = type AnsiString(1251);
var
  A: AnsiString;
  U: UnicodeString;
  U8: UTF8String;
  C: CyrillicString;
begin
  A := 'This is an AnsiString';
  Memo1.Lines.Add('AnsiString Codepage: ' + IntToStr(StringCodePage(A)));
  U := 'This is a UnicodeString';
  Memo1.Lines.Add('UnicodeString Codepage: ' + IntToStr(StringCodePage(U)));
  U8 := 'This is a UTF8string';
  Memo1.Lines.Add('UTF8string Codepage: ' + IntToStr(StringCodePage(U8)));
  C := 'This is a CyrillicString';
  Memo1.Lines.Add('CyrillicString Codepage: ' + IntToStr(StringCodePage(C)));
end;

Результатом выполнения приведенного выше кода будет:

The Codepage for an AnsiString is: 1252
The Codepage for an UnicodeString is: 1200
The Codepage for an UTF8string is: 65001
The Codepage for an CyrillicString is: 1251

Другие функции библиотеки RTL, связанные с кодировкой Unicode

Есть ряд других подпрограмм для преобразования строк из одной кодовой страницы в другую. В их числе:

  • UnicodeStringToUCS4String
  • UCS4StringToUnicodeString
  • UnicodeToUtf8
  • Utf8ToUnicode

Кроме того, в библиотеке RTL также появился тип RawByteString, который представляет собой тип строки, не связанный ни с какой кодировкой:

  RawByteString = type AnsiString($FFFF);

Тип RawByteString позволяет передавать строковые данные для любой кодовой страницы без каких-либо преобразований последней. Он особенно полезен для подпрограмм, для которых кодировка не имеет значения, например для побайтового поиска в строке. Обычно это означает, что параметры подпрограмм, которыми обрабатываются строки без связи с их кодовыми страницами, должны иметь тип RawByteString. Тип RawByteString следует присваивать переменным как можно реже, если вообще когда-либо, так как это может привести к непредсказуемому поведению и возможной потере данных.

Как правило, присвоения типов строк совместимы друг с другом.

Например, присвоение

MyUnicodeString := MyAnsiString;

будет выполнено, как и ожидалось — содержимое строки типа AnsiString будет помещено в строку типа UnicodeString. Как правило, можно присваивать один тип строки строке другого типа, и компилятор выполнит необходимые преобразования, если возможно.

Однако некоторые преобразования могут привести к потере данных, и необходимо остерегаться при перемещении из строки одного типа, которая включает данные в кодировке Unicode, в другую, тип которой не поддерживает Unicode. Например, можно присваивать тип UnicodeString строке типа AnsiString, но если строка типа UnicodeString содержит символы, которые не отображаются в активной в данный момент кодовой странице ANSI, то эти символы будут потеряны при преобразовании. Рассмотрим следующий код:

procedure TForm88.Button4Click(Sender: TObject);
var
  U: UnicodeString;
  A: AnsiString;
begin
  U := 'This is a UnicodeString';
  A := U;
  Memo1.Lines.Add(A);
  U := 'Добро пожаловать в мир Юникода с использованием Дельфи 2009!!';
  A := U;
  Memo1.Lines.Add(A);
end;

Результат выполнения этого кода, если текущая кодовая страница ОС — 1252, будет следующим:

This is a UnicodeString
????? ?????????? ? ??? ??????? ? ?????????????? ?????? 2009!!

Как можно видеть, при назначении типа UnicodeString строке типа AnsiString информация теряется,  так как символы кириллицы не отображаются кодовой страницей Windows-1252. Причина такого результата — строка UnicodeString содержала символы, не представимые в кодовой странице AnsiString, эти символы были потеряны и заменены вопросительными знаками при назначении типа UnicodeString строке типа AnsiString.

SetCodePage

Функция SetCodePage, объявленная в модуле System.pas как

procedure SetCodePage(var S: AnsiString; CodePage: Word; Convert: Boolean);

представляет собой новую функцию RTL, которой задается новая кодовая страница для строки типа AnsiString. Необязательным параметром Convert определяется, следует ли преобразовать сами данные строки в заданную кодовую страницу. Если значение параметра Convert — False, то для строки просто будет изменена кодовая страница. Если значение параметра Convert — True, то данные передаваемой строки будут преобразованы в заданную кодовую страницу.

Функция SetCodePage должна использоваться редко и с большой осторожностью. Обратите внимание, что, если кодовая страница не соответствует существующим данным строки (то есть значение параметра Convert  — False), то результаты могут оказаться непредсказуемыми. Кроме того, если существующие данные строки преобразованы, а в новой кодовой странице не представлен заданный исходный символ, данные могут потеряться.

Получение массива байтов TBytesиз строк

В составе библиотеки RTL есть также набор перегружаемых подпрограмм для извлечения из строки массива байтов. Как будет показано в части III, рекомендуется использовать в качестве буфера данных массив TBytes, а не строку. Библиотека RTL упрощает это за счет перегружаемых версий функции BytesOf(), принимающей в качестве параметра разные типы строк.

Заключение

Библиотека Tiburon’s Runtime Library теперь полностью поддерживает новый тип строки UnicodeString. В нее входят новые классы и подпрограммы для обработки и преобразования строк в кодировке Unicode, для управления кодовыми страницами и для упрощения перехода с более ранних версий.

В Части III будут рассмотрены специальные кодовые конструкции, которые необходимы, чтобы выяснить: готов ли тот или иной программный код к переходу на кодировку Unicode.

Наверх

    msm.ru

    Нравится ресурс?

    Помоги проекту!

    Пожалуйста, выделяйте текст программы тегом [сode=pas] … [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.


    Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
    1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
    2. Как «свернуть» программу в трей.
    3. Как «скрыться» от Ctrl + Alt + Del (заблокировать их и т.п.)
    4. Как прочитать список файлов, поддиректорий в директории?
    5. Как запустить программу/файл?
    … (продолжение следует) …


    Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
    Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


    Внимание
    Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
    Повторная попытка — 60 дней. Последующие попытки бан.
    Мат в разделе — бан на три месяца…

    >
    Кодировка строки: UTF-8,ANSI,Windows-1251
    , мистика полная :) 2 дня борюсь

    • Подписаться на тему
    • Сообщить другу
    • Скачать/распечатать тему

      


    Сообщ.
    #1

    ,
    30.05.11, 04:26

      Member

      **

      Рейтинг (т): 1

      Добрый день! Кто-то может мистику развеять? Буду благодарен очень.

      У меня Delphi 2010. Значит строки в unicode.

      загружаю google.ru в string (idHttp.Get), вывожу строку в showmessage — русские символы отображаются.
      Сохраняю страницу google.ru на диск, загружаю на хостинг, и опять загружаю в string — русские символы НЕ отображаются.

      В заголовке Гугла вообще пишется charset=UTF-8, а когда сохранил страницу — уже Windows-1251.

      В string русские символы отображаются нормально, если на сайтах кодировки Windows 1251,UTF-8.

      Сохраняю текстовые файлы в Total Commander с кодировками Windows-1251 и UTF-8, загружаю на сайт, получаю (idHttp.Get) обратно в string — русские символы НЕ отображаются.

      Прочитал статью СТАТЬЯ, по словам автора нужно с UTF-8 на Windows-1251 менять? Тогда почему сайты с UTF-8 и Windows-1251 нормально уже отображаются.

      Yandex — UTF-8 и отображается нормально в string.

      Сохраняю дерево TreeView и загружаю обратно, все ок. Беру этот же файл, загружаю на сервер — русские символы НЕ отображаются.

      Мне только одно помогает: сохранить в блокноте в ANSI, загрузить на сервер и сделать это:

      ExpandedWrap disabled

        function W1252To1251(const AData: String): String;

          var

            S: RawByteString;

            X: Integer;

          begin

            SetLength(S, Length(AData));

            for X := 1 to Length(AData) do

              S[X] := AnsiChar(AData[X]);

            SetCodePage(S, 1251, False);

            Result := S;

        end;

      В браузере: если сохранил в 1251 и в браузере то же стоит 1251 — все отображается, UTF-8 так же. То есть сервер ничего не подменяет. Экспериментировал с иным хостингом — так же ерунда.

      Я уже запутался, ничего понять не могу, прошу Вашей помоши.

      Master

      ViktorXP



      Сообщ.
      #2

      ,
      30.05.11, 05:20

        1)

        Цитата maxefficiently @ 30.05.11, 04:26

        — русские символы НЕ отображаются.

        Что в место их? знаки вопросов или корокозяблы?

        2) какая кодировка в заголовке от обеих серверов? (имеется ввиду не заголовок в html теле)
        подсмотреть можно в IdHTTP1.Response.CharSet (или с помощью FF + FireBug)

        Добавлено 30.05.11, 05:23
        пс. попробуй указать желаемую кодировку (IdHTTP1.Request.AcceptCharSet)


        CodeMonkey



        Сообщ.
        #3

        ,
        30.05.11, 05:31

          Посмотрите: Парсинг — проблема с кодировками

          ExpandedWrap disabled

            uses

              HtmlCPConvert;

            procedure TForm1.Button1Click(Sender: TObject);

            var

              Str: TMemoryStream;

              RawContent: RawByteString;

              Content: String;

            begin

              Str := TMemoryStream.Create;

              try

                IdHTTP1.Get(Edit1.Text, Str);

                SetLength(RawContent, Str.Size);

                Move(Str.Memory^, Pointer(RawContent)^, Str.Size);

              finally

                FreeAndNil(Str);

              end;

              Content := RawHTMLToHTML(RawContent);

              Memo1.Lines.Text := Content;

            end;

          Если на сервере кодировка указана верно, то это будет работать с любой кодировкой. Модули можно взять тут.

          Цитата maxefficiently @ 30.05.11, 04:26

          В заголовке Гугла вообще пишется charset=UTF-8, а когда сохранил страницу — уже Windows-1251

          Как сохраняешь-то? Если через SaveToFile у TStrings, то там по-умолчанию ANSI — что и есть Windows-1251.

          Цитата maxefficiently @ 30.05.11, 04:26

          Прочитал статью СТАТЬЯ, по словам автора нужно с UTF-8 на Windows-1251 менять?

          Не нужно. Зачем?


          Anatoly Podgoretsky



          Сообщ.
          #4

          ,
          30.05.11, 05:37

            Сохраняй UTF-8, а то все равно получишь крякозябры.
            Д2010 работает с Юинкодом и поддерживает его преобразование в UTF-8 автоматически.

            Добавлено 30.05.11, 05:39
            ИНДИ, в зависимсоти от версии не работает с Юникод, да и версии 10.х это бета версии, не бета Инди 9.


            maxefficiently



            Сообщ.
            #5

            ,
            30.05.11, 05:53

              Member

              **

              Рейтинг (т): 1

              Indy 10.5.5
              Вот сайт, можете попробовать:

              Сохранил в разных кодировках:

              Windows 1251
              UTF-8 Без ВОМ
              UTF-8 c BOM

              Использовал:
              idHttp, AcceptCharSet: ‘windows-1251,utf-8;q=0.7,*;q=0.7’;
              Language: ru-RU,ru;q=0.9,en;q=0.8
              так и оставлял поля пустыми.

              HTTP Analyzer ничего особенного не показал.

              Добавлено 30.05.11, 06:04
              ViktorXP, обычно крякозябры.

              CodeMonkey, сохраняю дерево TreeView и загружаю обратно, все ок. Беру этот же файл, загружаю на сервер, качаю с сервера в стринг, — русские символы НЕ отображаются. За статью: зачем автор тогда из UTF-8 в 1251 конвертирует, типа надо так, проблемы возникают.

              Сообщение отредактировано: maxefficiently — 30.05.11, 14:14


              Anatoly Podgoretsky



              Сообщ.
              #6

              ,
              30.05.11, 06:06

                Все три страницы показываются нормально. С BOM лучше всего.
                Но бардак в том, что у всех трех файлов отсутствует заголовок страницы.


                maxefficiently



                Сообщ.
                #7

                ,
                30.05.11, 06:09

                  Member

                  **

                  Рейтинг (т): 1

                  Anatoly Podgoretsky, это вы говорите, что в браузере показываются? Там да! Если в Delphi, какой код используете? Я просто: s:=form1.idhttp1.Get(‘http://xxx.com/UT8-BOM.v’);

                  Добавлено 30.05.11, 06:12
                  Вот типа такого постоянно получаю:user posted image


                  Fr0sT



                  Сообщ.
                  #8

                  ,
                  30.05.11, 06:16

                    У TStringList есть параметр Encoding в методе SaveToFile, если, конечно, сохранение идет через него. А по дефолту метод сохраняет в UTF-16.


                    maxefficiently



                    Сообщ.
                    #9

                    ,
                    30.05.11, 06:19

                      Member

                      **

                      Рейтинг (т): 1

                      Мне так надо было потом:
                      StrStream:=TStringStream.Create(s,tencoding.UT8); //перепробовал Unicode,Default,UTF7
                      form2.TreeView1.LoadFromStream(strstream);
                      StrStream.Free;

                      Добавлено 30.05.11, 06:26
                      Вот работает (TIdHTTPRequest оставил стандартным):
                      s:=idhttp1.Get(‘http://www.google.com.ua/’);
                      showmessage(s);
                      а с моим сайтом значит нет…

                      Добавлено 30.05.11, 06:32
                      И как говорил, работает один способ только: сохранить в ANSI, а потом после скачивания с сервера в 1251 конвертировать — тогда все ок.

                      Добавлено 30.05.11, 06:39
                      Fr0sT, я и в UTF-16 то же сохранял, во что только я не сохранял… :)

                      Сообщение отредактировано: maxefficiently — 30.05.11, 06:39


                      CodeMonkey



                      Сообщ.
                      #10

                      ,
                      30.05.11, 06:48

                        Я для кого ссылку давал?

                        Там показано, как получить страницу в виде «как есть».

                        Если делать:

                        ExpandedWrap disabled

                          s:=idhttp1.Get(‘http://www.google.com.ua/’);

                        То здесь Indy нахимичит с кодировками, как указано здесь: http://www.delphikingdom.ru/asp/answer.asp?IDAnswer=68134


                        maxefficiently



                        Сообщ.
                        #11

                        ,
                        30.05.11, 06:59

                          Member

                          **

                          Рейтинг (т): 1

                          CodeMonkey, так вывод, что Indy так хитро работает? Почему она то нормально работает, то хитрит…


                          CodeMonkey



                          Сообщ.
                          #12

                          ,
                          30.05.11, 07:05

                            Я вам говорю, что вы с Indy неправильно работаете.


                            maxefficiently



                            Сообщ.
                            #13

                            ,
                            30.05.11, 07:10

                              Member

                              **

                              Рейтинг (т): 1

                              CodeMonkey, понял-понял, спасибо большое, я там все читал, только не применял, думал проще есть способ и я туплю. Вам +1

                              Добавлено 30.05.11, 07:38
                              Товарищи, все ещё проще :) вот тут мне овтетил человек: ОТВЕТ

                              Сообщение отредактировано: maxefficiently — 30.05.11, 07:39

                              Master

                              ViktorXP



                              Сообщ.
                              #14

                              ,
                              30.05.11, 08:13

                                подобный прикол с String + Utf8 + Indy тоже наблюдал. но лечится банально загрузкой данный напрямую в TStringList минуя переменную String. и без доп. перекодировки

                                ExpandedWrap disabled

                                  ///  Strings: TStringList;  

                                    idhttp1.Get(‘http://xxx.com/UT8-BOM.v’, Strings);


                                maxefficiently



                                Сообщ.
                                #15

                                ,
                                30.05.11, 08:14

                                  Member

                                  **

                                  Рейтинг (т): 1

                                  так что сохраняйте полученное idHTTP в TMemoryStream и все будет ОК.

                                  Добавлено 30.05.11, 08:15
                                  ViktorXP, во-во!

                                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)

                                  0 пользователей:

                                  • Предыдущая тема
                                  • Delphi: Общие вопросы
                                  • Следующая тема

                                  Рейтинг@Mail.ru

                                  [ Script execution time: 0,0385 ]   [ 16 queries used ]   [ Generated: 4.02.23, 12:07 GMT ]  

                                  Понравилась статья? Поделить с друзьями:
                                • Delphi 7 скачать торрент для windows 7 x32 скачать торрент
                                • Delphi 7 скачать бесплатно для windows 7 x86
                                • Delphi 7 скачать бесплатно для windows 7 x32
                                • Devcon не является внутренней или внешней командой windows 10
                                • Devcon exe windows 10 x64 скачать