How to convert PAnsiChar to WideString or string?
Asked Answered
M

4

14

How do I convert a PAnsiChar variable to WideString or to string?

Megara answered 24/4, 2011 at 7:31 Comment(0)
S
15

You simply assign one variable to another and let the Delphi compiler do all the conversion for you:

var
  p: PAnsiChar;
  s: string;
  w: WideString;
....
s := p;
w := p;

If you want to convert in the other direction, and restricting the discussion to Delphi 7 for which Char, PChar, string are all ANSI data types you would use the following:

PAnsiChar(s);
PAnsiChar(AnsiString(w));

The casts are needed when going in this direction and in the case of the WideString the data must be explicitly converted from Unicode to ANSI before asking for a null-terminated C string pointer.

Soemba answered 24/4, 2011 at 7:37 Comment(10)
The compiler will do it for you, but not without complaining. You'll get W1057 Implicit string cast from 'AnsiChar' to 'string' and W1057 Implicit string cast from 'AnsiChar' to 'WideString' if you do this.Boride
@Wouter Not in Delphi 7 which has an ANSI string.Soemba
@wouter Interesting point you make though. On a Unicode Delphi I turn off the warnings about string conversions that go from ansi to unicode since there is no data loss. But I can imagine use cases where you want to know about such conversions.Soemba
@David: there MAY BE data loss when going from Ansi->Unicode or Unicode->Ansi, depending on whether the strings use any characters > #127. That is why the warnings exist in the first place.Intumesce
You can lose data if the wrong codepage is used during the conversion. When assigning an AnsiChar/AnsiString to a WideString, or vice versa, D2007 and earlier use the OS default codepage for the conversion. If the Ansi data is using a different codepage, then a mismatch occurs and the Ansi data won't be interpretted correctly. When dealing with Ansi data, you have to deal with Ansi codepages as well, and there is a lot of different ones in use around the world. In D2009 and later, AnsiString is codepage-aware now. Unicode was designed to eliminate these kind of issues for good.Intumesce
@Remy In that case, using an explicit cast isn't going to help. Nothing short of fixing the codepage is going to help.Soemba
Using an explicit cast gets rid of the implicit cast warnings in D2009+. They also help the compiler decide which conversions you actually wanted to have performed. And as I said, AnsiString is codepage-aware in D2009+, so explicit casting also helps the compiler decide which codepages to use, as AnsiString type aliases with static codepage affinities can be defined in code now.Intumesce
@remy so you are asserting that explicit cast changes the meaning of the code? Are you sure?Soemba
An explicit cast tells the compiler exactly what you want done, so it does not have to guess in places where implicit casts can be ambiquious and thus potentially do the wrong thing.Intumesce
Crikey, this is hilarious! Where's Andreas!Cutinize
S
4
var
  s: AnsiString;
  w: WideString;
  p: PAnsiChar;
...
  s := p;
  w := WideString(s);
Shafting answered 24/4, 2011 at 7:35 Comment(0)
B
2

s:PAnsiChar;

WideString(AnsiString(s));

Or on unicode Delphi's you probably want:

String(AnsiString(s));
Boride answered 24/4, 2011 at 7:34 Comment(2)
There is no need for these casts.Soemba
+1 I have a personal 'use case' that requires the compiler to stfu! (:-D)Cutinize
C
1

Look for StrPas function in docs.

Chronaxie answered 24/4, 2011 at 7:33 Comment(8)
I don't think it's good practice to use StrPas() in new code. Also keep in mind that in FPC it'll truncate your string: freepascal.org/docs-html/rtl/strings/strpas.htmlBoride
@Woulter now re-read the question. It was not about FPC. So your opinion is completely subjective and ungrounded.Quicksand
I didn't vote this down though. StrPas() probably does the job in most cases, but recommending it is something else...Boride
if I recall correctly, StrPas became obsolete when Delphi 2 was released. It will get the job done but I wouldn't say it was good advice.Soemba
By the way, take a look at StrPas itself in Delphi7: function StrPas(const Str: PChar): string; begin Result := Str; end;.Boride
@David the function is not "obsolete". The function is provided for compatibility, it's updated and it makes code more readable as it shows explicitly what happens. Now, having the function helps adaptation of the code to Delphi Prism or other compilers (more to come).Quicksand
The documention states: This function is provided for backwards compatibility only. To convert a null-terminated string to an AnsiString or native Delphi language string, use a typecast or an assignment.Soemba
delphi prism argument doesn't work for me. Where would you get a PAnsiChar from in .net?Soemba

© 2022 - 2024 — McMap. All rights reserved.