Cast string as record?

Hi.

I have a string, the first part of which contains characters in a known pattern. After that, it's
padded with rubbish to an unknown length. Something like: 
'abc1234e.................................................'

I'd like to access the initial known part of the string as if it were a record.

type
   MyRecord=record
     MyCode: array[1..3] of char;
     MyNum: array[1..4] of char;
     MyChar: char;
  end;

var
  r: MyRecord;
  s: string

s:='abc1234e.................................................'
r:=MyRecord(s)

and then access the first part of the string

MyLabel.Caption:=r.MyCode[2]

But the compiler doesn't like the cast. Is this an impossible thing to do?

Regards,
Richard
0
richard
8/15/2008 11:32:13 PM
embarcadero.delphi.general 4258 articles. 0 followers. Follow

3 Replies
1890 Views

Similar Articles

[PageSpeed] 25
Get it on Google Play
Get it on Apple App Store

richard@tortoise.demon.co.uk wrote:
> I have a string, the first part of which contains characters in a known pattern. After that, it's
> padded with rubbish to an unknown length. Something like: 
> 'abc1234e.................................................'
> 
> I'd like to access the initial known part of the string as if it were a record.
> 
> type
>    MyRecord=record
>      MyCode: array[1..3] of char;
>      MyNum: array[1..4] of char;
>      MyChar: char;
>   end;
> 
> var
>   r: MyRecord;
>   s: string
> 
> s:='abc1234e.................................................'
> r:=MyRecord(s)
> 
> and then access the first part of the string
> 
> MyLabel.Caption:=r.MyCode[2]
> 
> But the compiler doesn't like the cast. Is this an impossible thing to do?

It's not impossible, but it's certainly ill-advised.

Anyway, remember that your string s is really a reference to the 
character data. The characters aren't stored in the variable's space 
itself. Ultimately, s is a pointer. So type-cast it to a pointer type.

type
   PCodeNum = ^TCodeNum;
   TCodeNum = packed record
     Code: array[0..2] of Char;
     Num: array[0..3] of Char;
     C: Char;
   end;
var
   s: string;
   r: PCodeNum;

s := 'abc1234e';
r := PCodeNum(s);
Assert(r.Num[0] = '1');
Assert(r.C = 'e');

I say this is ill-advised because it relies on knowing the memory layout 
of the string data type. I'd prefer to only rely on the contents of the 
string. You can use the Copy function to extract a piece of a string.

-- 
Rob
0
Rob
8/15/2008 11:50:05 PM
Hi Rob,

Thanks for your advise on how to make this technique work, together with your cautions.

>type
>   PCodeNum = ^TCodeNum;
>   TCodeNum = packed record
>     Code: array[0..2] of Char;
>     Num: array[0..3] of Char;
>     C: Char;
>   end;
>var
>   s: string;
>   r: PCodeNum;
>
>s := 'abc1234e';
>r := PCodeNum(s);
>Assert(r.Num[0] = '1');
>Assert(r.C = 'e');

I did wonder why you have not dereferenced r, although experimenting, it seems that if I have a
pointer to a record, and I want to reference the fields of that record, I can do so without
explicitly dereferencing the pointer, ie

MyChar := r.Num[0]

can be used instead of

MyChar := r^.Num[0]


Regards,
Richard
0
richard
8/16/2008 9:37:27 PM
richard@tortoise.demon.co.uk wrote:
> I did wonder why you have not dereferenced r, although experimenting, it seems that if I have a
> pointer to a record, and I want to reference the fields of that record, I can do so without
> explicitly dereferencing the pointer, ie
> 
> MyChar := r.Num[0]
> 
> can be used instead of
> 
> MyChar := r^.Num[0]

Right. Delphi has always worked that way.

-- 
Rob
0
Rob
8/17/2008 4:05:03 PM
Reply: