Delphi: 如何从字符串中获取*真实的* ASCII 码
Delphi: How to get the *real* ASCII code from a string
这让我发疯。我已经两天没有成功地将我的字符串从一种类型转换为另一种类型。
我正在使用 Delphi Rio,我需要将字符串转换为 HEX 或 DEC,但该字符串包含特殊字符,例如 á é í ó ú ñ 或 €。
例如,'á' 字符是 160(十进制)或 A0(十六进制)。
但是,根据字符串类型(ansichar、utf8、widechar ...),我得到 225、145、241,但我不知道如何获得真正的 160 值。
我需要这个,因为我想将特殊字符发送到蓝牙打印机。
如果我发送这个:
edit1.text := 'áéíóú€$';
FSocket.SendData(TEncoding.ASCII.GetBytes(edit1.Text));
打印机收到这个(十六进制):
3F 3F 3F 3F 3F 3F 24
但是,它应该收到这个 (HEX):
A0 82 A1 A2 A3 D5 24
那是因为我得到的每个字符的 ASCII 值都是错误的(63 是 '?' 字符的 ASCII 码)。
所以...我怎样才能将真正的 ASCII 文本发送到打印机?
如何获得'á'(160)的真实ascii码?
请帮忙!
首先,对于超过0x7F的字符,没有真正的 ASCII码。 ASCII 仅定义 7 位字符。当考虑使用 8 位字符范围的上半部分 (0x80->0xFF) 中的字符进行文本编码时,编码不再是 ASCII, but ANSI,并且有数百种不同的编码方案,所有这些方案都支持不同种类的特殊的角色。 ANSI 编码方案完全相互不兼容是开发和迁移到 Unicode 的主要驱动因素之一。
我们可以从您的预期输出中推断出您尝试映射到的 ANSI 代码页是 Code Page 858。您的打印机手册可能在某处告诉您这一点,但现在我们假设这是打印机接受的唯一输入。 阅读您的手册 总是一个好主意 - 它们会在未来为您省去无尽的麻烦。正如 David 指出的那样,如果您可以使用 Unicode,那么这应该始终是您的首选,也是最佳选择。
您可以使用 TEncoding
class 提取所需的字节,例如:
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
这让我发疯。我已经两天没有成功地将我的字符串从一种类型转换为另一种类型。
我正在使用 Delphi Rio,我需要将字符串转换为 HEX 或 DEC,但该字符串包含特殊字符,例如 á é í ó ú ñ 或 €。
例如,'á' 字符是 160(十进制)或 A0(十六进制)。 但是,根据字符串类型(ansichar、utf8、widechar ...),我得到 225、145、241,但我不知道如何获得真正的 160 值。
我需要这个,因为我想将特殊字符发送到蓝牙打印机。 如果我发送这个:
edit1.text := 'áéíóú€$';
FSocket.SendData(TEncoding.ASCII.GetBytes(edit1.Text));
打印机收到这个(十六进制):
3F 3F 3F 3F 3F 3F 24
但是,它应该收到这个 (HEX):
A0 82 A1 A2 A3 D5 24
那是因为我得到的每个字符的 ASCII 值都是错误的(63 是 '?' 字符的 ASCII 码)。
所以...我怎样才能将真正的 ASCII 文本发送到打印机? 如何获得'á'(160)的真实ascii码?
请帮忙!
首先,对于超过0x7F的字符,没有真正的 ASCII码。 ASCII 仅定义 7 位字符。当考虑使用 8 位字符范围的上半部分 (0x80->0xFF) 中的字符进行文本编码时,编码不再是 ASCII, but ANSI,并且有数百种不同的编码方案,所有这些方案都支持不同种类的特殊的角色。 ANSI 编码方案完全相互不兼容是开发和迁移到 Unicode 的主要驱动因素之一。
我们可以从您的预期输出中推断出您尝试映射到的 ANSI 代码页是 Code Page 858。您的打印机手册可能在某处告诉您这一点,但现在我们假设这是打印机接受的唯一输入。 阅读您的手册 总是一个好主意 - 它们会在未来为您省去无尽的麻烦。正如 David 指出的那样,如果您可以使用 Unicode,那么这应该始终是您的首选,也是最佳选择。
您可以使用 TEncoding
class 提取所需的字节,例如:
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