我正在寻找一种简单的方法,从TStringList (总是“Windows1252”文本文件)获取一行十六进制数据,并将它们分割成记录块(每行可以有不同的长度)。
在Delphi 7中,我使用了:
procedure DecodeLineAddr(const aLine: AnsiString; var ByteCount: integer; var Address:Cardinal; var RecType: Integer);
begin
//123 4567 89 0
//:10 4640 00 0000 0600 0200 fa00 004f 7800 1e00 fb00 88
ByteCount:= StrToInt('$' + copy(aLine, 2, 2));
Address := StrToInt('$' + copy(aLine, 4, 4));
RecType := StrToInt('$' + copy(aLine, 8, 2));
end;
也就是说,只需从行中的初始“块信息”中的正确位置复制字符,然后在'$‘前面加上一个’StrToInt‘,以便StrToInt将字符串解释为十六进制。
我一条条地处理-所以做这样的事情很容易:
aLineAsTBytes:= TEncoding.ASCII.GetBytes(aStringLst[ndx]);
然后将aLineAsTBytes作为TBytes而不是AnsiString传递到DecodeLineAddr。
我不清楚应该如何解码各种字节(或如何适当地分割它们),以便用桌面和移动代码返回正确的结果。
也就是说,如果使用aLine:TBytes (而不是AnsiString),那么相当于:
ByteCount:= StrToInt('$' + copy(aLine, 2, 2));
(是否有更好/更快的方法来处理这个问题?)
蒂娅。
EdB
发布于 2015-12-07 03:24:13
你已经在做的事情会起作用,但你需要做一些调整。最重要的是,将函数转换为"string“类型,而不是"AnsiString”类型,这意味着您必须转换它。
移动字符串是基于0的,因此在移动上,您需要从索引中减去1。或者您也可以使用my ()或zcopy()函数,它们在所有平台上都执行相同的操作。如果您正在处理旧的windows代码,请使用ocopy(),它将从本质上将您的基于0的字符串视为基于1的字符串,从而使其更易于移植。
const
{$IFNDEF MSWINDOWS}
STRZ = 1;
{$ELSE}
STRZ = 0;
function zcopy(sString: string; iStartZeroBased: nativeint; iLength: nativeint): string;
begin
result := '';
setlength(result, lesserof(iLength, length(sString)-iStartZerobased));
movemem32(@result[strz], @sString[(strz+iStartZeroBased)], length(result)*sizeof(char));
end;
function ocopy(sString: string; iStartOneBased: nativeint; iLength: nativeint): string;
begin
result := zcopy(sString, iStartOneBased-1, iLength);
end;
接下来,以这段代码为例,它不是一个完全完整的解决方案,但它将为您在移动平台上提供大部分ansi字符串支持(还有一些关于指针的警告)。但基本上,您可以通过简单地将一个字符串赋值给字符串类型或相反的诗句来转换字符串。我不得不将它从几个依赖项中破解出来,这样我就不能保证它会立即编译,但是它应该非常接近。
unit iosbytestring;
interface
uses
sysutils, classes;
{$IFNDEF MSWINDOWS}
const STRZERO = 0;
{$ELSE}
const STRZERO = 1;
{$ENDIF}
type
Tiosansichar = packed record
private
b: byte;
class function AnsiFromChar(c: char): byte;static;
class function CharFromAnsi(b: byte): char;static;
public
function ToChar: char;
function ToOrd: byte;
class operator Implicit(const s: Tiosansichar): string;
class operator Implicit(const s: Tiosansichar): char;
class operator Implicit(const s: Tiosansichar): byte;
class operator Implicit(const s: Tiosansichar): pointer;
end;
Tiosbytestring = record
private
Fbytes: TBytes;
function GetChar(idx: nativeint): char;
procedure SetChar(idx: nativeint; const Value: char);
function GetAddrOf(idx: nativeint): pbyte;
function getbyte(idx: nativeint): byte;
procedure setbyte(idx: nativeint; const Value: byte);
public
property chars[idx: nativeint]: char read GetChar write SetChar;
property bytes[idx: nativeint]: byte read getbyte write setbyte;
property addrof[idx: nativeint]: pbyte read GetAddrOf;
class operator Implicit(const s: TIOSByteString): string;
class operator Implicit(const s: string): TIOSByteString;
class operator Add(const s1,s2: TIOSByteString): TIOSByteSTring;
class operator Add(const s1: string; const s2: TIOSByteString): TIOSByteSTring;
class operator Add(const s1: TIOSByteString; const s2: string): TIOSByteSTring;
procedure FromString(s: string);
function ToString: string;
procedure SetLength(i: nativeint);
end;
TIOSAnsiString = TIOSByteString;
{$IFNDEF MSWINDOWS}
ansistring = TIOSByteString;
utf8string = TIOSByteString;
widestring = string;
{$ENDIF}
implementation
{ iosbytestring }
class operator Tiosbytestring.Add(const s1: string;
const s2: TIOSByteString): TIOSByteSTring;
var
ss2,ss3: string;
begin
ss2 := s2.ToString;
ss3 := s1+ss2;
result.FromString(ss3);
end;
class operator Tiosbytestring.Add(const s1: TIOSByteString;
const s2: string): TIOSByteSTring;
var
ss1,ss3: string;
begin
ss1 := s1.ToString;
ss3 := ss1+s2;
result.FromString(ss3);
end;
procedure Tiosbytestring.FromString(s: string);
begin
Fbytes := TEncoding.ANSI.GetBytes(s);
end;
function Tiosbytestring.GetAddrOf(idx: nativeint): pbyte;
begin
result := @Fbytes[idx];
end;
function Tiosbytestring.getbyte(idx: nativeint): byte;
begin
result := Fbytes[idx-strzero];
end;
function Tiosbytestring.GetChar(idx: nativeint): char;
begin
result := Tiosansichar.CharFromAnsi(Fbytes[idx-strzero]);
end;
class operator Tiosbytestring.Implicit(const s: TIOSByteString): string;
begin
result := s.ToString;
end;
class operator Tiosbytestring.Implicit(const s: string): TIOSByteString;
begin
result.FromString(s);
end;
procedure Tiosbytestring.setbyte(idx: nativeint; const Value: byte);
begin
Fbytes[idx-strzero] := value;
end;
class operator Tiosbytestring.Add(const s1,
s2: TIOSByteString): TIOSByteSTring;
var
ss1,ss2,ss3: string;
begin
ss1 := s1.ToString;
ss2 := s2.ToString;
ss3 := ss1+ss2;
result.FromString(ss3);
end;
procedure Tiosbytestring.SetChar(idx: nativeint; const Value: char);
begin
Fbytes[idx-strzero] := Tiosansichar.AnsiFromChar(value);
end;
procedure Tiosbytestring.SetLength(i: nativeint);
begin
system.setlength(Fbytes,i);
end;
function Tiosbytestring.ToString: string;
begin
result := TEncoding.ANSI.GetString(Fbytes);
end;
{ Tiosansichar }
class function Tiosansichar.AnsiFromChar(c: char): byte;
var
s: string;
te: TEncoding;
b: TBytes;
begin
s := c;
b := TEncoding.ANSI.GetBytes(c);
result := b[0];
end;
class function Tiosansichar.CharFromAnsi(b: byte): char;
var
s: string;
bytes: TBytes;
begin
system.setlength(bytes, 1);
bytes[0] := b;
s := TEncoding.ANSI.GetString(bytes, 0, 1);
result := s[low(s)];
end;
class operator Tiosansichar.Implicit(const s: Tiosansichar): char;
begin
result := s.ToChar;
end;
class operator Tiosansichar.Implicit(const s: Tiosansichar): string;
begin
result := s.ToChar;
end;
class operator Tiosansichar.Implicit(const s: Tiosansichar): pointer;
begin
result := @s.b;
end;
class operator Tiosansichar.Implicit(const s: Tiosansichar): byte;
begin
result := s.b;
end;
function Tiosansichar.ToChar: char;
begin
result := CharFromAnsi(b);
end;
function Tiosansichar.ToOrd: byte;
begin
result := b;
end;
end.
因此,只需添加上面的单元,将其添加到uses子句中,然后神奇地,您的移动平台上将有一个ansistring类型。继续在windows上使用标准的字符串类型。
如果一切顺利..。这就是您的代码片段最终可能会出现的情况。
procedure DecodeLineAddr(const aLine: AnsiString; var ByteCount: integer; var Address:Cardinal; var RecType: Integer);
var
aLineWide: string;
begin
aLineWide = aLine;
//123 4567 89 0
//:10 4640 00 0000 0600 0200 fa00 004f 7800 1e00 fb00 88
ByteCount:= StrToInt('$' + ocopy(aLineWide, 2, 2));
Address := StrToInt('$' + ocopy(aLineWide, 4, 4));
RecType := StrToInt('$' + ocopy(aLineWide, 8, 2));
end;
https://stackoverflow.com/questions/34124112
复制相似问题