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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 26.05.2017, 11:08   #1
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию utf8toansi не работает в DelphiXE?

Здравствуйте.
Решил перенести код по обработке сайта из D7 в DXE. Но встречаю то одну, то другую загвоздку... Одну из них вообще не знаю как решить. В D7 для получения нормальных русских букв пользовался функцией utf8toansi. DXE даёт после этой функции вместо русских букв знаки вопроса. Как с этим быть? Чем заменить эту функцию, чтобы получать нормальную страницу?
И, если никто не против, заодно задам вопрос, который никак не могу понять: как перевести текст из кодировки, используемой в D7 (ansi) в кодировку DXE (unicode) и наоборот?
Ship_1 вне форума Ответить с цитированием
Старый 26.05.2017, 13:54   #2
eoln
Старожил
 
Аватар для eoln
 
Регистрация: 26.04.2008
Сообщений: 2,689
По умолчанию

Цитата:
для получения нормальных русских букв пользовался функцией utf8to...
Смотря откуда текст берётся и каким способом. И куда получение происходит? В саму программу/компоненты? XE юникодная, и некоторые способы загрузки с дефолтными параметрами уже преобразовывают текст в готовую строку. В то же время "старые" методы обработки тоже работают. Обычно проблема бывает при совместном использовании таких способов.
Полагаю, идет преобразование уже преобразованного. В этом случае надобность в этой функции отпадает вовсе.

Цитата:
как перевести текст из кодировки, используемой в D7 (ansi) в кодировку DXE (unicode) и наоборот
Имеется ввиду код программы с кириллицей? Или получение/запись в файл? Или ещё что-то? В разных случаях это либо требуется, либо происходит "само собой" )

Кажется, ответ больше запутывает чем распутывает ))
eoln вне форума Ответить с цитированием
Старый 26.05.2017, 14:17   #3
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Ship_1
В XE это сделано через одно место. Короче всё с ног на голову поставили.

Перекодировать куда откуда. Из массива байт Bytes в строку типа Unicode.
Код:
s:=TEncoding.Unicode.GetString(Stream.Bytes);
Выше код не всегда работает. Подзабыл что именно возможно он автоматически не определяет Ansi, а только делает выборку из юникода. Поэтому я использую. Encoding:=Nil; принуждает к автоматическому определению кодировки.

Код:
var
  Encoding:TEncoding;
  MyUnicode:TEncoding;
begin
     Encoding:=Nil;
     MyUnicode:=TEncoding.UNICODE.Create;
     TEncoding.GetBufferEncoding(Stream.Bytes, Encoding, MyUnicode);
     Text:=Encoding.GetString(Stream.Bytes);
end;
А так хотя string[i] и выдаёт д-ух байтовые символы но string внутри содержит код кодировке. Поэтому внутри могут находиться строки с любой кодировкой.
Но этого как раз и следует избегать. На входе в программу все строки следует приводить в Unicode.

utf8toansi - заменяется
Код:
var
  unt8String:String;
  AnsiString:AnsiString;
begin
AnsiString:=TEncoding.Ansi.GetString(unt8String);
PS. Под рукой XE нету. Писал прям тут мог и ошибиться.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .

Последний раз редактировалось Pavia; 26.05.2017 в 14:29.
Pavia вне форума Ответить с цитированием
Старый 26.05.2017, 14:27   #4
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

Текст страницы в StringList.Text через idHTTP.Get (без каких-либо дополнительных параметров и свойств)
Код:
html.Text:=TEncoding.Unicode.GetString(TBytes(html.Text));
не помогло
Код:
      unt8Str:=Form1.idHTTP1.Get('http://privet.ru/search/music/?go=1&query='+URLCode(Zapros)+'&ss=music');
      AnsiStr:=TEncoding.ASCII.GetString(TBytes(unt8Str));
      ClipBoard.AsText:='http://privet.ru/search/music/?go=1&query='+URLCode(ZaprKompozits)+'&ss=music';
      html.Text:=AnsiStr;
выдало вообще только один единственный символ "<" и всё.

Последний раз редактировалось Ship_1; 26.05.2017 в 14:51.
Ship_1 вне форума Ответить с цитированием
Старый 26.05.2017, 15:21   #5
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

простите, никак не могу понять, что не получается.
насколько я слышал, в XE уже нормальный Unicode поддерживается.
поэтому:
Код:
html.Text:=Form1.idHTTP1.Get('http://privet.ru/search/music/?go=1&query='+URLCode(Zapros)+'&ss=music');
без всех этих танцев с бубнами.

или я что-то не понимаю?

p.s. html - это какой контрол?
и зачем нужен Ansi, если есть Unicode?
Serge_Bliznykov вне форума Ответить с цитированием
Старый 26.05.2017, 15:41   #6
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

Serge_Bliznykov, без обработки выходит вот такой результат:
Цитата:
"caption":"\u041c\u043e\u044f \u0441\u0442\u0440\u0430\u043d\u043 8\u0446\u0430"
Хотя там же в коде и обычная кириллица присутствует в заголовке страницы, но только внутри кода. Всё, что отображается на самой странице - отображается так:
Цитата:
����� - �����������
html - это обычный TStringList
На всякий случай вот код функции URLCode (может, в ней чего не то, хотя браузером ссылка воспринимается адекватно и idHTTP данные грузит)
Код:
  function URLCode(URL:string):string;
  var
    i:integer;
    URLCode1,URLCode2,URLCode3,URLCode4:string;
    ch:Char;
  begin
    Result:='';
    URLCode1:=AnsiToUTF8(URL);
    URLCode2:=WideCharToString(PWideChar(URL));
    URLCode3:=AnsiString(URL);
    URLCode4:=WideString(URL);
    For i:=1 to length(URL) do
    begin
      ch:=URL[i];
      if (Ord(ch)>1039) and (Ord(ch)<1088) then begin Result:=Result+'%'+IntToHex(Ord(ch)-848+53200,4); insert('%',Result,length(Result)-1); end
      else
      if (Ord(ch)>1087) and (Ord(ch)<1104) then begin Result:=Result+'%'+IntToHex(Ord(ch)-848+53392,4); insert('%',Result,length(Result)-1); end
      else
      if (ch='ё') then  Result:=Result+'%D1%91'
      else
      if (ch='Ё') then  Result:=Result+'%D0%81'
      else
      if (ch='’') or (ch='''') then  Result:=Result+'%E2%80%99'
      else Result:=Result+URL[i];
    end;
  end;
В D7 всё отлично работало, функция (её часть, которую для XE я изменил) выглядела так:
Код:
      if (Ord(ch)>191) and (Ord(ch)<240) then begin Result:=Result+'%'+IntToHex(Ord(ch)+53200,4); insert('%',Result,length(Result)-1); end
      else
      if (Ord(ch)>239) and (Ord(ch)<256) then begin Result:=Result+'%'+IntToHex(Ord(ch)+53392,4); insert('%',Result,length(Result)-1); end
      else

Последний раз редактировалось Ship_1; 26.05.2017 в 15:55.
Ship_1 вне форума Ответить с цитированием
Старый 26.05.2017, 18:33   #7
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Так там ничего и не надо.
Код:
function GetPage(URL:String; var Text:String):Boolean;
var
 HTTP: TIdHTTP;
 IdHandler:TIdSSLIOHandlerSocketOpenSSL;
begin
 Result:=False;
try
 IdHandler := TIdSSLIOHandlerSocketOpenSSL.Create (nil);
 HTTP := TIdHTTP.Create(nil);
 HTTP.IOHandler := IdHandler;
//  HTTP:=IdHTTP1;
  HTTP.HandleRedirects:=true;
  HTTP.ConnectTimeout:=3000;
  HTTP.ReadTimeout:=3000;
  try
    Text:=HTTP.Get(URL);
    if Pos('200', HTTP.ResponseText) <>0 then
       begin
         result:=True;
       end;
  finally
    HTTP.Destroy;
  end;
except

end;
end;


procedure TForm1.Button2Click(Sender: TObject);
var str:String;
begin
GetPage('http://privet.ru/search/music/?go=1&query='+ TIdURI.PathEncode('test')+'&ss=music', Str);
memo2.Text:=str;
end;
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 29.05.2017, 10:16   #8
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

Pavia, полностью скопировал, всё равно для кириллицы не помогло.
Цитата:
����� - �����������
(приложил что получается если сохранить ответ в файл)
Вложения
Тип файла: txt Probe1.txt (48.9 Кб, 17 просмотров)
Ship_1 вне форума Ответить с цитированием
Старый 29.05.2017, 10:24   #9
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

Цитата:
Сообщение от Ship_1 Посмотреть сообщение
Pavia, полностью скопировал, всё равно для кириллицы не помогло.
что значит - "не помогло"?!
покажите, пожалуйста, скриншот, где видно Memo2 с загруженным в него текстом.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 29.05.2017, 12:36   #10
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

Прошу прощения за свою оплошность... Я сохранял результат в файл html и открывал через браузер, там получались приведённые мной символы. Сейчас после замечания посмотрел сам txt, и, вроде, сами результаты запроса в нормальной кодировке. Меня сбивали присутствующие в txt строки вида
Цитата:
"caption":"\u0410\u0443\u0434\u0438 \u043e\u0437\u0430\u043f\u0438\u044 1\u0438"
Большое спасибо!
Ship_1 вне форума Ответить с цитированием
Ответ


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

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Не работает анимация. Механизм работает лишь при изменения числа в едит1. Студент ММИ Помощь студентам 1 18.05.2015 07:39
Ошибка "cannot resolve unit name" при переносе проекта с Delphi7 на DelphiXE Ferkel Общие вопросы Delphi 1 16.06.2012 13:01
не работает relese версия проги и debug работает тока на моем компе D][mon C# (си шарп) 2 04.05.2012 20:21
QuickReport for DelphiXE ArtGrek Компоненты Delphi 1 14.10.2011 13:00
Почему программа на С++ не работает с локальным описанием массива, но работает с глобальным? >>STINGER<< Помощь студентам 4 08.03.2011 09:56