Delphi: Как получить * реальный * ASCII-код из строки - PullRequest
2 голосов
/ 04 марта 2020

Это сводит меня с ума. Два дня я безуспешно преобразовывал свою строку из одного типа в другой.

Я использую Delphi Rio, и мне нужно преобразовать строку в HEX или DE C, но строка содержит специальные символы, такие как é é í ó ú ñ или €.

Например, символ «á» равен 160 (de c) или A0 (hex). Тем не менее, я получаю 225, 145, 241 в зависимости от типа строки (ansichar, utf8, widechar ...), но я не знаю, как я могу получить реальное значение 160.

Мне нужно это потому что я хочу отправить специальные символы на принтер Bluetooth. Если я отправлю это:

edit1.text := 'áéíóú€$';
FSocket.SendData(TEncoding.ASCII.GetBytes(edit1.Text));

Принтер получит это (HEX):

3F 3F 3F 3F 3F 3F 24

Однако оно должно получить это (HEX):

A0 82 A1 A2 A3 D5 24

Это потому что я получаю неправильное значение ASCII для каждого символа (63 является кодом ascii для символа '?').

Итак ... как я могу отправить настоящий текст ASCII на принтер? Как я могу получить настоящий код ASCII для 'á' (160)?

Пожалуйста, помогите!

1 Ответ

11 голосов
/ 04 марта 2020

Во-первых, не существует такой вещи как real ASCII-код для символов за пределами 0x7F. ASCII определяет только 7-битные символы. При рассмотрении кодировки текста с использованием символов в верхней половине (0x80-> 0xFF) 8-разрядного диапазона символов кодировки больше не ASCII , но ANSI , и существуют сотни различных схем кодирования, каждая из которых поддерживает различные варианты специальных символов. Полная взаимная несовместимость схем кодирования ANSI является одним из основных драйверов для разработки и перехода на Unicode.

Из ваших ожидаемых результатов мы можем сделать вывод, что кодовая страница ANSI, которую вы пытаетесь отобразить, равна Code Страница 858 . Ваше руководство по принтеру, вероятно, где-то говорит вам об этом, но пока мы будем предполагать, что это единственный вход, который принимает принтер. всегда полезно прочитать ваши руководства - они избавят вас от бесконечных головных болей в будущем. Как отметил Дэвид, если вы можете использовать Unicode, это всегда должно быть вашим первым, лучшим вариантом.

Вы можете извлекать нужные байты, используя класс TEncoding, например:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var      
  LEncoding : TEncoding;
  tb : TBytes;
  b : Byte;
begin
  LEncoding := TEncoding.GetEncoding(858);
  try
    tb := LEncoding.GetBytes('áéíóú€$');
  finally
    LEncoding.Free;
  end;
  for b in tb do Write(IntToHex(b,2) + ' ');    
  ReadLn;    
end.

Это приводит к выводу:

 A0 82 A1 A2 A3 D5 24
...