我有 delphi 应用程序,我需要为 OS X 重写它。 此应用程序向/从 HID 设备写入/读取数据。
我在尝试从 mac 写入字符串时遇到问题。
这是我正在写的行(来自 Windows 上的调试器):'Новый комплекс 1' 这很好用。同时,如果将其从调试器复制到某个地方,它会变成“Íîâûé êîìïëåêñ 1”。设备以西里尔文原样显示它。没关系。
当我尝试在 OS X 上重复此步骤时,设备显示无法读取的符号。但是,如果我从 Windows 示例中对 'Íîâûé êîìïëåêñ 1' 进行硬编码,它又可以了。
给一些提示。
如何在 Windows 上运行
一些代码:
s:= 'Новый комлекс 1'
s:= AnsiToUtf8(ReplaceNull(s));
这里是 ReplaceNULL:
function ReplaceNull(const Input: string): string;
var
Index: Integer;
Res: String;
begin
Res:= '';
for Index := 1 to Length(Input) do
begin
if Input[Index] = #0 then
Res:= Res + #$12
else
Res:= Res + Input[Index];
end;
ReplaceNull:= Res;
end;
我把这个字符串放到 Tstringlist 然后保存到文件:
ProgsList.SaveToFile(Mwork.pathLibs+'stream.ini', TEncoding.UTF8);
其他程序读取这个列表然后写入设备:
Progs:= TStringList.Create();
Progs.LoadFromFile(****);
s:= UTF8ToAnsi(stringreplace(Progs.Strings[i], #$12, #0, [rfReplaceAll, rfIgnoreCase]));
然后写入设备。
所以写的那一行看起来是这样的:
"'þ5'#0'ÿ'#$11'Новый комплекс 1'#0'T45/180;55;70;85;90;95;100;T45/180'#0'ÿ'"
在 Mac 上我成功地得到了相同的字符串。但是设备无法用西里尔文显示。
Delphi
string
在所有平台上都以 UTF-16 编码。无需转换它,除非您在应用程序外部与非 Unicode 数据进行交互。
话虽如此,如果您有一个以特定字符集编码的字节数组,您可以使用 Delphi 的
TEncoding.Convert()
方法将其转换为另一个字符集。您可以使用 TEncoding.GetEncoding()
方法获取特定字符集的 TEncoding
对象(如果不同于标准支持的字符集 - ANSI、ASCII、UTF-7、UTF-8 和 UTF-16 - 这在TEncoding
).中有自己的财产获取者
var
SrcEnc, DstEnc: TEncoding;
SrcBytes, ConvertedBytes: TBytes;
begin
SrcBytes := ...; // Cyrillic encoded bytes
SrcEnc := TEncoding.GetEncoding('Cyrillic'); // or whatever the real name is...
try
DstEnc := TEncoding.GetEncoding('Windows-1251');
try
ConvertedBytes := TEncoding.Convert(SrcEnc, DstEnc, SrcBytes);
finally
DstEnc.Free;
end;
finally
SrcEnc.Free;
end;
// use ConvertedBytes as needed...
end;
Update:要在特定字符集中编码 Unicode 字符串,只需调用
TEncoding.GetBytes()
方法,例如:
s := 'Новый комлекс 1';
Enc := TEncoding.GetEncoding('Windows-1251');
try
bytes := Enc.GetBytes(s);
finally
Enc.Free;
end;
s := 'Новый комлекс 1';
bytes := TEncoding.UTF8.GetBytes(s);
TEncoding.GetString()
将特定字符集中的字节解码回字符串,例如:
bytes := ...; // Windows-1251 encoded bytes
Enc := TEncoding.GetEncoding('Windows-1251');
try
s := Enc.GetString(bytes);
finally
Enc.Free;
end;
bytes := ...; // UTF-8 encoded bytes
s := TEncoding.UTF8.GetString(bytes);
接下来是答案。 Delphi Berlin 10.1 使用 KOI8-R,我的设备是 cp1251。 因为我想写俄罗斯符号(西里尔文),所以我为 KOI8-R 和 cp1251 的符号创建了匹配表。
所以,我把 KOI8-R 中的字符串放在 cp1251 中。
简单代码:
Dict:=TDictionary<String,String>.Create;
Dict.Add(#$439,#$E9);//'й'
Dict.Add(#$44E,#$FE);//'ю'
Dict.Add(#$430,#$E0);//'а'
....
function tkoitocp.getCP1251Code(str:string):string;
var i:integer; res,key,val:string; pair:Tpair<String,String>;
begin
res:='';
for i:=1 to length(str) do
begin
if dict.ContainsKey(str[i]) then
begin
pair:= dict.ExtractPair(str[i]);
res:=res+pair.Value;
dict.Add(pair.Key,pair.Value);
end
else
res:=res+str[i];
end;
Result:=res;
end;