Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 911
  • Last Modified:

String Question...

How do i convert a PAnsiChar string that is retrieved from a record back to a normal string:

ie: if the PAnsiChar string is returned as:  aaaa#0bbbb#0cccc#0dddd#0

i want to break the PAnsiChar string up into a normal string that will have aaaabbbbccccdddd in it
0
mantra246
Asked:
mantra246
  • 5
  • 4
  • 2
  • +3
1 Solution
 
MamouriCommented:
Hi!

Just use StrCopy fiunction. It must solve the problem

Regards
0
 
mantra246Author Commented:
StrCopy and StrLCopy only copies to the first #0  - i need to be able to get the entire line.
0
 
zebadaCommented:
PAnsiChar strings are defined to end at the first #0.
How do you decide where the end of your data is?

Regards
Paul
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
mantra246Author Commented:
It is information that is returned by windows in a record - the record contains a list of items with each being ended by a #0 - when i try to get the list it only gives me the first one and not the rest that i know is there.
0
 
zebadaCommented:
Then you should define a record in Delphi to accept the data.
For your example data:

TMyRecord = record
  astr: array[0..4] of char; /* Note: must start with 0 index and be large enough to accommodate the #0 terminator char. */
  bstr: array[0..4] of char;
  cstr: array[0..4] of char;
  dstr: array[0..4] of char;
end;

var
  myrecord: TMyRecord;
  var a,b,c,d: string;
begin
  SomeWindowFunction(@MyRecord);
  a := PChar(MyRecord.aStr);
  b := PChar(MyRecord.bStr);
  c := PChar(MyRecord.cStr);
  d := PChar(MyRecord.dStr);
end;

By the way most windows structures are already defined as Delphi records.

Regards
Paul
0
 
jcondeCommented:
what about

procedure TForm1.Button1Click(Sender: TObject);
const
  ANSI_LENGTH = 20;
var
  P: PAnsiChar;
  S: String;
  I: Integer;
begin
  P := 'aaaa' + #0 + 'bbbb' + #0 + 'cccc' + #0 + 'dddd' + #0;
  for I := 0 to ANSI_LENGTH do
  begin
    If (P + I)^ <> #0 then
      S := S + (P + I)^;
  end;
  showmessage(s);
end;
0
 
jcondeCommented:
my above code has a minor bug ... it should be:

for I := 0 to ANSI_LENGTH -1 do

instead of

for I := 0 to ANSI_LENGTH  do
0
 
jcondeCommented:
Since you're dealing with binary data, you MUST know the length of the PAnsiChar variable ... That's unless you have a terminating character at the end of the PAnsiChar string
0
 
Wim ten BrinkCommented:
I guess the end is marked by a double #0, so walk through the data until you're at the end of it all. An example:

program Project1;

{$APPTYPE CONSOLE}

const
  Data = 'aaaa'#0'bbbbb'#0'ccccccccccc'#0#0;

var
  Value: PAnsiChar = Data;
  Loop: PAnsiChar;
  Line: string;

begin
  Line := Value;
  Loop := Value;
  while (Length(Line) > 0) do begin
    WriteLn(Line);
    while (Loop^ <> #0) do
      Inc(Loop);
    Inc(Loop);
    Line := Loop;
  end;
  Write('Press <Enter>. ');
  ReadLn;
end.

However, if the end of the list isn't ended with a double #0#0 but if you have a fixed amount of elements then you'll need to loop <number_of_items> times through the string value.
0
 
mocartsCommented:
hi, all :)
just my two cents..
basically code is same as provided by Alex, but shorter (not faster)

procedure SplitPCharArray(aList: TStrings; pac: PAnsiChar);
var
  l: integer;
begin
  aList.BeginUpdate;
  try
    aList.Clear;
    l := StrLen(pac);
    while l > 0 do begin
      aList.Add(pac);
      inc(pac, l+1);
      l := strLen(pac);
    end;
  finally
    aList.EndUpdate;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  SplitPCharArray(Memo1.Lines, 'aaaa'+#0+'bbbb'+#0+'cccc'+#0#0);
end;

wbr, mo.
0
 
mocartsCommented:
oops :) you don't  need to split :) ok, here will be join.

function JoinPCharArray(pac: PAnsiChar): string;
var
  l: integer;
begin
  l := StrLen(pac);
  while l > 0 do begin
    Result := Result + pac;
    inc(pac, l+1);
    l := strLen(pac);
  end;
end;
0
 
jcondeCommented:
I think mocarts has it ....
0
 
zebadaCommented:
> It is information that is returned by windows in a record - the record contains a list of items with each being ended by a #0

What is Windows definition of the record?
Why would you want to "parse" the record structure yourself?
That seems like a very backwards way of getting the returned data from the Window's function.
I cannot possibly imagine that Windows would pass back a string constructed like that.

Regards
Paul

0
 
jcondeCommented:
zebada,

Although I agree its a very weird way of inter-communicating with a "windows record", I do know several News Feed agents transmit their information (via a VPN, Cable, E0, etc..) just like that ...
0
 
zebadaCommented:
Good point!
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 5
  • 4
  • 2
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now