首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Delphi中从TBytes数据转换十六进制字符串

在Delphi中从TBytes数据转换十六进制字符串
EN

Stack Overflow用户
提问于 2015-12-06 23:22:43
回答 1查看 1.7K关注 0票数 0

我正在寻找一种简单的方法,从TStringList (总是“Windows1252”文本文件)获取一行十六进制数据,并将它们分割成记录块(每行可以有不同的长度)。

在Delphi 7中,我使用了:

代码语言:javascript
运行
复制
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将字符串解释为十六进制。

我一条条地处理-所以做这样的事情很容易:

代码语言:javascript
运行
复制
aLineAsTBytes:= TEncoding.ASCII.GetBytes(aStringLst[ndx]);

然后将aLineAsTBytes作为TBytes而不是AnsiString传递到DecodeLineAddr。

我不清楚应该如何解码各种字节(或如何适当地分割它们),以便用桌面和移动代码返回正确的结果。

也就是说,如果使用aLine:TBytes (而不是AnsiString),那么相当于:

代码语言:javascript
运行
复制
ByteCount:= StrToInt('$' + copy(aLine, 2, 2));

(是否有更好/更快的方法来处理这个问题?)

蒂娅。

EdB

EN

Stack Overflow用户

回答已采纳

发布于 2015-12-07 03:24:13

你已经在做的事情会起作用,但你需要做一些调整。最重要的是,将函数转换为"string“类型,而不是"AnsiString”类型,这意味着您必须转换它。

移动字符串是基于0的,因此在移动上,您需要从索引中减去1。或者您也可以使用my ()或zcopy()函数,它们在所有平台上都执行相同的操作。如果您正在处理旧的windows代码,请使用ocopy(),它将从本质上将您的基于0的字符串视为基于1的字符串,从而使其更易于移植。

代码语言:javascript
运行
复制
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字符串支持(还有一些关于指针的警告)。但基本上,您可以通过简单地将一个字符串赋值给字符串类型或相反的诗句来转换字符串。我不得不将它从几个依赖项中破解出来,这样我就不能保证它会立即编译,但是它应该非常接近。

代码语言:javascript
运行
复制
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上使用标准的字符串类型。

如果一切顺利..。这就是您的代码片段最终可能会出现的情况。

代码语言:javascript
运行
复制
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;
票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34124112

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档