fischermx
asked on
How to concatenate a string with a pchar that contains a null
This is a simplified example of what I have in my application:
And it works.
But my question is if there's a function already that allows me to do this.
I tried many way of concatenate the string, StrCopy, Copy, Move, and nothing worked, may be I didn't do it correctly.
Thanks in advance!
function ConcatThis(const s : String; pc : PChar; iPCharLen : Integer): String;
var
sTmp : String;
i : Integer;
begin
sTmp := s;
for i := 0 to iPCharLen-1 do
begin
sTmp := sTmp+pc[i];
end;
result := sTmp;
end;
var
pch : PAnsiChar;
s, rs : String;
begin
pch := PAnsiChar(#0'tt');
s := 'asdf';
rs := ConcatThis(s, pch);
// result is asdf#0tt
And it works.
But my question is if there's a function already that allows me to do this.
I tried many way of concatenate the string, StrCopy, Copy, Move, and nothing worked, may be I didn't do it correctly.
Thanks in advance!
Can you show your code please?
Hi my friend,
Use PWideChar instead of PAnsiChar then you can use WideCharLenToString like below:
var
pch :PWideChar;
s, rs : String;
begin
pch := #0'tt';
s := 'asdf';
rs:= s + WideCharLenToString(pch, 3);
// result is asdf#0tt
Use PWideChar instead of PAnsiChar then you can use WideCharLenToString like below:
var
pch :PWideChar;
s, rs : String;
begin
pch := #0'tt';
s := 'asdf';
rs:= s + WideCharLenToString(pch, 3);
// result is asdf#0tt
ASKER
jimyX:
Thanks for the correction, I typed it manually. That's my code.
I can't post the original, it's too large.
Reza:
The PAnsiChar comes from an external interfase. I can't change types.
I can use PChar or PAnsiChar.
Thanks for the correction, I typed it manually. That's my code.
I can't post the original, it's too large.
Reza:
The PAnsiChar comes from an external interfase. I can't change types.
I can use PChar or PAnsiChar.
So is line 19 below correct?
BTW, why creating concatenate function while there is one already in Delphi:
function StrCat(Dest:Pchar; src:Pchar):PChar;
Did you try it?
function ConcatThis(const s : String; pc : PChar; iPCharLen : Integer): String;
var
sTmp : String;
i : Integer;
begin
sTmp := s;
for i := 0 to iPCharLen-1 do
begin
sTmp := sTmp+pc[i];
end;
result := sTmp;
end;
var
pch : PChar;
s, rs : String;
begin
pch := PChar('#0tt'); // You will not be able to concatenate 'asdf' + #0'tt'. Your string will always be 'asdf'
s := 'asdf';
rs := ConcatThis(s, pch, length(pch));
// result is asdf#0tt
end;
BTW, why creating concatenate function while there is one already in Delphi:
function StrCat(Dest:Pchar; src:Pchar):PChar;
Did you try it?
I meant line 18
Here is an example from Delphi 7 about StrCopy and StrCat:
procedure TForm1.Button1Click(Sender: TObject);
var
Buffer: PChar;
begin
GetMem(Buffer,Length('asdf') + Length('#0tt') + 1);
StrCopy(Buffer, PChar('asdf'));
StrCat(Buffer, PChar('#0tt'));
showmessage(Buffer);
FreeMem(Buffer);
end;
In order to give us an idea about what you are facing, could you make a smaller sample of your code to show the issue that you have with StrCopy, Copy and Move please?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
First, you do know hat #0 (null character) signifies the end of a null terminated string (hence the name null terminated), so the method showed that worked for you will never work with any delphi function that converts pchar to string
Once the functions encounter the #0, the string is terminated, effectively the example you gave here #0'tt' is a blank string
Now converting PChar to a string is quite simple
s := string(pchar)
It seems you are trying to do something that is not conventional so you will have to stick to your own methods. No delphi function is going to help you in this case
The delphi way to do this would be
function ConcatThis(const s : String; pc : PChar): String;
begin
Result := s + String(pc);
end;
This would give you back the result ' asdf', since #0 signifies end of your string
If you want it your way, stick to using character buffers of variable length only. But again, once you convert them to strings, your string will be truncated at the first position of #0. And don't even think of using this in windows APIs, you will always get incorrect values back
ASKER
Reza:
Thank you!! That's the solution that worked!
Thank you!! That's the solution that worked!
ASKER
ewangoya:
I do know what that #0 character is.
I do know that what I'm doing is not normal.
Now, your statement that "your string will be truncated at the first position of #0" it's a bit of... mmh.... not totally correct.
You're probably talking that when using that string in a UI, it will look truncated. But I never say I was trying to show this value to a user.
The fact is a string is able to hold null values in any position.
It's not normal to do that. But in my situation, I'm working with other's people components, and I can't change the way they wrote it.
I do know what that #0 character is.
I do know that what I'm doing is not normal.
Now, your statement that "your string will be truncated at the first position of #0" it's a bit of... mmh.... not totally correct.
You're probably talking that when using that string in a UI, it will look truncated. But I never say I was trying to show this value to a user.
The fact is a string is able to hold null values in any position.
It's not normal to do that. But in my situation, I'm working with other's people components, and I can't change the way they wrote it.
ASKER
jimix:
Your solution will fail because Length('#0tt') will return 0, and then everything else fails.
Your solution will fail because Length('#0tt') will return 0, and then everything else fails.
@fischermx
<mmh....not totally correct>
Of course I'm correct, there is a difference between string and PChar,
PChar is null terminated, here is my statement
But again, once you convert them to strings, your string will be truncated at the first position of #0
Show me a PChar that will convert to a string beyond the null character, I might probably have to re-learn Delphi and C++
ASKER
ewangoya:
My pleasure:
var
s, spch: string;
pch : PAnsiChar;
rs : String;
begin
pch:= #0'tt';
s:= 'asdf';
SetString(spch, pch, 3);
A PAnsiChar is converted to a String and still preserve its nulls! ;)
My pleasure:
var
s, spch: string;
pch : PAnsiChar;
rs : String;
begin
pch:= #0'tt';
s:= 'asdf';
SetString(spch, pch, 3);
A PAnsiChar is converted to a String and still preserve its nulls! ;)
SetString copies contents of a given buffer to a string variable, it is not converting the buffer to a string.
This functions exactly the way you did your solution by moving a block of characters from one memory location to another, It is not converting the PChar to a string
ASKER
Ok, then give me an example of a real conversion.
What do you mean by my solution will fail?
This will work:
Length('#0tt')
But this one will not work:
Length(#0'tt')
This will work:
Length('#0tt')
But this one will not work:
Length(#0'tt')
ASKER
jimyX:
'#0tt' is a #, plus a 0, plus a t, plus a t.
#0'tr' is a null, plus a t, plus a t.
I need the second, as I show in my original question, so it won't work.
'#0tt' is a #, plus a 0, plus a t, plus a t.
#0'tr' is a null, plus a t, plus a t.
I need the second, as I show in my original question, so it won't work.
ASKER
So, well, I have to correct the way I said it.
Your solution will fail because you're using Length('#0tt') which is not the same string (#0'tt) I have to use as I show in my original post.
Your solution will fail because you're using Length('#0tt') which is not the same string (#0'tt) I have to use as I show in my original post.
Best regards
Open in new window