Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

How to concatenate a string with a pchar that contains a null

Posted on 2011-03-20
20
Medium Priority
?
1,771 Views
Last Modified: 2012-05-11
This is a simplified example of what I have in my application:

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

Open in new window



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!


0
Comment
Question by:fischermx
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 6
  • 3
  • +1
20 Comments
 
LVL 24

Expert Comment

by:jimyX
ID: 35174857
Change it to this:
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('#0tt');
  s := 'asdf';

  rs := ConcatThis(s, pch, length(pch));

  // result is asdf#0tt

Open in new window

0
 
LVL 24

Expert Comment

by:jimyX
ID: 35174860
Can you show your code please?
0
 
LVL 2

Expert Comment

by:RezaSadigh
ID: 35174865
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
0
Technology Partners: 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!

 
LVL 1

Author Comment

by:fischermx
ID: 35174910
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.


0
 
LVL 24

Expert Comment

by:jimyX
ID: 35174920
So is line 19 below correct?
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;

Open in new window


BTW, why creating concatenate function while there is one already in Delphi:
function StrCat(Dest:Pchar; src:Pchar):PChar;
Did you try it?
0
 
LVL 24

Expert Comment

by:jimyX
ID: 35174923
I meant line 18
0
 
LVL 24

Expert Comment

by:jimyX
ID: 35174938
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;

Open in new window

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?
0
 
LVL 2

Accepted Solution

by:
RezaSadigh earned 2000 total points
ID: 35175001
Sorry for delay
Ok, so try this one

var
  s, spch: string;
  pch : PAnsiChar;
  rs : String;
begin
  pch:= #0'tt';
  s:= 'asdf';
  SetString(spch, pch, 3); // replace 3 by pch Length

  rs:= s + spch;
  // result is asdf#0tt
end;

Best regards
Reza
0
 
LVL 32

Expert Comment

by:Ephraim Wangoya
ID: 35175641

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
0
 
LVL 1

Author Comment

by:fischermx
ID: 35177890
Reza:

Thank you!! That's the solution that worked!

0
 
LVL 1

Author Comment

by:fischermx
ID: 35177912
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.

0
 
LVL 1

Author Comment

by:fischermx
ID: 35177915
jimix:

Your solution will fail because Length('#0tt') will return 0, and then everything else fails.

0
 
LVL 32

Expert Comment

by:Ephraim Wangoya
ID: 35180854

@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++
0
 
LVL 1

Author Comment

by:fischermx
ID: 35183390
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! ;)

0
 
LVL 32

Expert Comment

by:Ephraim Wangoya
ID: 35184170

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
0
 
LVL 1

Author Comment

by:fischermx
ID: 35186243

Ok, then give me an example of a real conversion.



0
 
LVL 24

Expert Comment

by:jimyX
ID: 35186280
What do you mean by my solution will fail?

This will work:
Length('#0tt')

But this one will not work:
Length(#0'tt')
0
 
LVL 1

Author Comment

by:fischermx
ID: 35192733
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.
0
 
LVL 1

Author Comment

by:fischermx
ID: 35192836
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.
0
 
LVL 2

Expert Comment

by:RezaSadigh
ID: 35220784
Best regards
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…
Suggested Courses

636 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question