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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 26.01.2017, 15:16   #1
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию Delphi7 и (Windows-1251, UTF-16) как сдружить?

Надеюсь, это реально сделать какой-нибудь умной самописной функцией, которую кто-нибудь знает? Или ещё как-то по-хитрому... Или хоть юнитом каким-нибудь.... Главное, чтоб без установки компонентов. В самом крайнем случае могла бы прокатить dll, если уж по-другому совсем никак. Потому что по-простому, видимо, нельзя, т.к. в интернете мне так и не удалось найти как это сделать.
На всякий случай сама задача: есть принтер сетевой, у которого есть веб-интерфейс, у которого есть страница с очередью. Проблема в том, что в очереди иногда появляются строки в этой кодировке. В самом веб-интерфейсе они отображаются "иероглифами", но средствами интернет-декодеров удалось понять, что это Windows-1251, UTF-16. Как такое можно отобразить в Delphi 7?
Пример:
Цитата:
㐭ㄴ峎죑尳⸠퇲⃐峝ㅜ���⻏탑⸳
㄰⸱ⴱ㜮ㄩ就㈠쇠㈸⸰ ⃑⃭

Последний раз редактировалось Ship_1; 26.01.2017 в 15:28.
Ship_1 вне форума Ответить с цитированием
Старый 26.01.2017, 16:00   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

WideCharToMultiByte kernel32.dll если что. Можно и самому написать тщательно изучив устройство utf16. Что будешь делать если там не ансиишные символы, типа китайско-турецких или еще чего?
а Windows-1251 это есть однобайтная кириллическая ансистринг, cp1251 еще, д7 без проблем ее понимает и с ней работает
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 26.01.2017 в 16:02.
Аватар вне форума Ответить с цитированием
Старый 26.01.2017, 16:42   #3
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

2cyr.com про эти символы пишет: "Исходная кодировка: Windows-1251, отображаемая как: UTF-16". Я, вообще-то, толком не пойму даже как это понять. То ли cp1251, отображаемая в UTF-16 выглядит иероглифами, то ли иероглифы, декодированные через cp1251 и выведенные как UTF-16 выглядят как нормальный текст.
Что-то нашёл функцию, но не пойму что к чему...
Код:
function UnicodeToAnsiString(const ws: WideString; codePage: Word): AnsiString;
 overload;
var
 l: integer;
begin
 if ws = '' then
   Result := ''
 else
 begin
   l := WideCharToMultiByte(codePage,
     WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,
     @ws[1], -1, nil, 0, nil, nil);
   SetLength(Result, l - 1);
   if l > 1 then
     WideCharToMultiByte(codePage,
       WC_COMPOSITECHECK or WC_DISCARDNS or WC_SEPCHARS or WC_DEFAULTCHAR,
       @ws[1], -1, @Result[1], l - 1, nil, nil);
 end;
end;
при коде 1200 (UTF-16 отсюда) ничего не выводит. При 1251 выводит то же, что и вообще без этой функции
Цитата:
яю-441О\СИ3\ .тСдаяиР Э\тскада а\1эяэяэяП.СР3.( 011.1-.7)11\ 2аБкл а820.
А должно быть
Цитата:
4-14\ОИС\3. Стадия Р\Эстакада 1\яэяэяэ.ПРС.3 (10.1-17.1)\12 Балка 28.0м. Схема напрягаемого армировани
P.S. Строку получаю из файла
Код:
  TmpStrL:=TStringList.Create;
  TmpStrL.LoadFromFile('CodeText.txt');
и беру TmpStrL[0], в которой это и записал.

Последний раз редактировалось Ship_1; 26.01.2017 в 16:48.
Ship_1 вне форума Ответить с цитированием
Старый 27.01.2017, 13:34   #4
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,774
По умолчанию

Цитата:
Сообщение от Ship_1 Посмотреть сообщение
P.S. Строку получаю из файла
Код:
  TmpStrL:=TStringList.Create;
  TmpStrL.LoadFromFile('CodeText.txt');
и беру TmpStrL[0], в которой это и записал.
Хоть убей, не могу представить, как в этом случае в строке оказываются иероглифы. В Delphi 7 это невозможно. Как вариант, строка приходит частично или полностью битой, поэтому если получилось восстановить -- надо благодарить бога.

Зато я знаю, как эти иероглифы получить:
Код:
const
  A: AnsiString = '4-14\ОИС\3. Стадия Р\Эстакада 1\яэяэяэ.ПРС.3 (10.1-17.1)\12 Балка 28.0м. Схема напрягаемого армировани'#0;
begin
  MessageBoxW(0, Pointer(A), nil, 0);
end;
Vapaamies вне форума Ответить с цитированием
Старый 27.01.2017, 13:41   #5
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

А тот CodeText.txt сюда вложением можно?
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 27.01.2017, 14:07   #6
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
А тот CodeText.txt сюда вложением можно?
Загрузил, заодно и со скрином как это выглядит в веб-интерфейсе.
И даже заодно фрагмент html сохранённого. Только поменял расширение на txt, т.к. html тут в разрешённых не присутствует.
Изображения
Тип файла: png Иероглифы.png (19.4 Кб, 125 просмотров)
Вложения
Тип файла: txt CodeText.txt (322 байт, 148 просмотров)
Тип файла: txt Фрагмент.txt (647 байт, 137 просмотров)
Ship_1 вне форума Ответить с цитированием
Старый 27.01.2017, 15:18   #7
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

В Фрагмент.txt точно не utf16
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 27.01.2017, 15:21   #8
Ship_1
Форумчанин
 
Регистрация: 10.02.2014
Сообщений: 526
По умолчанию

Если его в html переименовать и открыть браузером, то появится тот самый вид.
Ну 2cyr именно как "Исходная кодировка: Windows-1251, отображаемая как: UTF-16" позволил отобразить его в правильном виде...
Ship_1 вне форума Ответить с цитированием
Старый 28.01.2017, 10:05   #9
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,774
По умолчанию

Код:
var
  Source: WideString;
  P, Head, Tail, Limit: PWideChar;
  S, Decoded: AnsiString;
  I: Integer;
begin
  with TFileStream.Create('T:\Фрагмент.txt', fmOpenRead or fmShareDenyWrite) do
  try
    SetLength(S, Size);
    ReadBuffer(S[1], Length(S));
  finally
    Free;
  end;
  Source := Utf8Decode(S);
  P := Pointer(Source);
  if P <> nil then
  begin
    Limit := P + Length(Source);
    while (P^ < WideChar($8000)) and (P < Limit) do
      Inc(P);
    if P < Limit then
    begin
      Head := P;
      Inc(P);
      while (P^ <> '<') and (P < Limit) do // берем до начала </font>
        Inc(P);
      if P < Limit then
      begin
        Tail := P;
        SetString(Decoded, PAnsiChar(Head), (Tail - Head) * SizeOf(WideChar));
        ShowMessage(Decoded);
      end;
    end;
  end;
end;
Vapaamies вне форума Ответить с цитированием
Старый 28.01.2017, 10:50   #10
Vapaamies
Ваш К. О.
Участник клуба
 
Аватар для Vapaamies
 
Регистрация: 26.12.2012
Сообщений: 1,774
По умолчанию

Написал второй вариант, для второго файла. Так и не смог понять, почему он вторую строку не определяет по переводу строки:
Код:
var
  Source: WideString;
  P, Head, Tail, Limit: PWideChar;
  S, Decoded: AnsiString;
  I: Integer;
begin
  with TFileStream.Create('T:\CodeText.txt', fmOpenRead or fmShareDenyWrite) do
  try
    SetLength(Source, Size div SizeOf(WideChar));
    ReadBuffer(Source[1], Length(Source));
  finally
    Free;
  end;
  P := Pointer(Source);
  if P <> nil then
  begin
    Inc(P);
    Limit := P + Length(Source);
    Head := P;
    while P < Limit do
    begin
      while (P^ <> #13) and (P^ <> #10) and (P < Limit) do
        Inc(P);
      Tail := P;
      if Head^ >= WideChar($20FF) then
        SetString(Decoded, PAnsiChar(Head), (Tail - Head) * SizeOf(WideChar))
      else
      begin
        SetLength(Decoded, Tail - Head);
        WideCharToMultiByte(CP_ACP, 0, Head, Tail - Head, Pointer(Decoded), Length(Decoded), nil, nil);
      end;
      ShowMessage(Decoded);
      if (P^ = #13) and (P[1] = #10) then
        Inc(P);
      Inc(P);
      Head := P;
    end;
  end;
end;
В целом же могу сказать, что это больше похоже на утечку памяти в программе, поскольку данные только похожи на осмысленные, а на самом деле перемешаны, и среди текста встречаются двоичные коды. При утечках остатки текста могут оставаться в памяти, поскольку компиляторы обычно распределяют данные с выравниванием, из-за чего текст сохраняется в мертвом пространстве, а в некоторых местах прерывается двоичными данными.
Vapaamies вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
utf-8 -> windows-1251 Lihosvet Visual C++ 10 03.09.2022 16:37
UTF-8 to WINDOWS-1251 Zanooda Общие вопросы Delphi 9 20.07.2011 08:13
php перекодировка из utf-8 в windows-1251 world12_tk PHP 3 25.04.2010 22:55
UTF-8 в Windows-1251 - нужна функция motorway PHP 3 04.07.2009 15:28