分拆字符串 (200分)

  • 主题发起人 主题发起人 nkiller
  • 开始时间 开始时间
N

nkiller

Unregistered / Unconfirmed
GUEST, unregistred user!
拆分一个字符串,请提供源代码:
MyString := 'Bssssss0IIIIRRRR';
说明:
B 表示一个 Byte 型数据;
ssssss0 表示一个标准字符串,0 表示以 #0 结束;
IIII 表示一个 Integer 型数据;
RRRR 表示一个 Real 型数据;

字符串16进制数据(示例)
03 6D 69 73 73 00 14 00 00 00 48 96 8B 44

将此字符转换成下面的记录:
type
MyRecord = record
rByte : Byte;
rString : String;
rInteger : Integer;
rReal : Real;
End;

如有错误,请指教,谢谢
 
使用字符串函数解析即可,如:
function PosEx(const SubStr, S: string; Offset: Cardinal = 1): Integer;
function Copy(S; Index, Count: Integer): string;
function Copy(S; Index, Count: Integer): array;
function StrToInt(const S: string): Integer;
function StrToFloat(const S: string): Extended; overload;
function StrToFloat(const S: string; const FormatSettings: TFormatSettings): Extended; overload;
详细的请参见Delphi帮助。
 
我主要就是不想那么麻烦,例如,可以将字符串当做一个 Buffer ??
另外,上面提供的16进制的数据是真实的数据,可以试试拆分。
还有就是,最后4位的 Float 型数据其实是表示时间的,如果可以,请帮忙转换,谢谢。
最后,请务必提供详尽的源码。
 
type
MyRecord = record
rByte : Byte; //1
rString : String; //7
rInteger : Integer; //4
rReal : Tdatetime; //4
End; //16
AMyRecord = array [0..10] of MyRecord;
var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
a:array [0..255] of char;
bb:AMyRecord;
i,n:integer;
time:TDatetime;
tems:string;
begin
a:='Bssssss013457965';
// bb[0].rByte :=a[0];
bb[0].rByte :=1;
for i:=1 to 7 do
begin
tems := tems+a;
end;
bb[0].rString := tems;
tems:='';
for i:=8 to 11 do
begin
tems := tems+a;
end;
bb[0].rInteger := strtoint(tems);
tems:='';
for i:=12 to 15 do
begin
tems := tems+a;
end;
bb[0].rReal := StrToTime(tems);
end;
 
下面是我写的代码:
type
RPlayer = record
Index: Integer;
Name: String;
Kill: Integer;
Time: Real;
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
Var
Player : RPlayer;
cPos : Integer;
MyStr, Hexs : String;
begin
// 09 4E 65 77 4E 61 6D 65 00 07 00 00 00 0B 1B 1B 45
MyStr := Chr($09) + Chr($4E) + Chr($65) + Chr($77) + Chr($4E);
MyStr := MyStr + Chr($61) + Chr($6D) + Chr($65) + Chr($00);
MyStr := MyStr + Chr($07) + Chr($00) + Chr($00) + Chr($00);
MyStr := MyStr + Chr($0B) + Chr($1B) + Chr($1B) + Chr($45);
// MyStr 才是真正会传入的数据样子,它严格意义上说根本不能算是字符串

Player.Index := Ord(MyStr[1]);
// Byte 类型,占一位,它的值是 9

cPos := Pos(#0,MyStr);
//寻找字符串结束标志 $00 的位置 cPos=9
//测试程序,未写容错部分,假定值存在
Player.Name := MidStr(MyStr,2,cPos-2);
//取得字符串部分,长度为7,值为 'NewName'
//这个部分的长度是不固定的,当前的长度是7,总是以 $00 结束
//4E 65 77 4E 61 6D 65 00

//紧接着的4个字节是 Integer 型数据,高位在后
Hexs := '$' + IntToHex(Ord(MyStr[cPos+4]),2);
Hexs := Hexs + IntToHex(Ord(MyStr[cPos+3]),2);
Hexs := Hexs + IntToHex(Ord(MyStr[cPos+2]),2);
Hexs := Hexs + IntToHex(Ord(MyStr[cPos+1]),2);
// Hexs 的结果是 '$00000007'
//07 00 00 00
Player.Kill := StrToInt(Hexs);
// Player.Kill 的值是 7

//最后的4个字节是 Float 型数据,高位在后
Hexs := '$' + IntToHex(Ord(MyStr[cPos+8]),2);
Hexs := Hexs + IntToHex(Ord(MyStr[cPos+7]),2);
Hexs := Hexs + IntToHex(Ord(MyStr[cPos+6]),2);
Hexs := Hexs + IntToHex(Ord(MyStr[cPos+5]),2);
// Hexs 的结果是 '$451B1B0B'
//0B 1B 1B 45
//这个值我处理不了,它是 Float 型数据,应该是用来表示时间的
//它的16进制值是 $451B1B0B
end;
 
下面是个 C 的例子,我想要的就是类似下面的方法
buf 就是传入的‘字符串’部分

int id = (int)*buf;
buf += 1;

string p_name = buf;
buf += p_name.length()+1;

int frags = (int)*buf;
buf += 4;

float time = (float)*buf;
buf += sizeof(float);

Player pl;
pl.setOnline(time);
pl.setName(p_name);
pl.setFrags(frags);
players[p_name] = pl;
 
RRRR 表示一个 Real 型数据;
是8个字节
 
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
MyRecord = record
rByte: Byte;
rString: string;
rInteger: Integer;
rReal: Real;
end;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

function getMyRecord(str: string): MyRecord;
var
rByte: Byte;
rString: string;
rInteger: Integer;
rReal: single; ////////////
l: integer;
begin
Move(str[1],rByte, SizeOf(rByte));

l := length(str) - SizeOf(rByte) - SizeOf(rInteger) - SizeOf(rReal) - 1;
setlength(rString, l);
Move(str[1 + SizeOf(rByte)],rString[1], l);
Move( str[1 + SizeOf(rByte) + l + 1],rInteger, SizeOf(rInteger));
Move( str[1 + SizeOf(rByte) + l + 1 + SizeOf(rInteger)],rReal, SizeOf(rReal));

result.rByte := rByte;
result.rString := rString;
result.rInteger := rInteger;
result.rReal := rReal;

end;

procedure TForm1.Button1Click(Sender: TObject);
var
m:MyRecord ;
begin
//03 6D 69 73 73 00 14 00 00 00 48 96 8B 44

m:=getMyRecord(#$03#$6D#$69#$73#$73#$00#$14#$00#$00#$00#$48#$96#$8B#$44);
showmessage(m.rString) ;
showmessage(floattostr(m.rReal))

end;

end.

 
没仔细看
用move吧
 
呵呵,正是我所期望的,万分感谢,已经分配积分。[:D][:D]
 
后退
顶部