14

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

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Little Helper
  • 2,419
  • 9
  • 37
  • 67

4 Answers4

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.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 3
    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. – Wouter van Nifterick Apr 24 '11 at 07:49
  • 1
    @Wouter Not in Delphi 7 which has an ANSI string. – David Heffernan Apr 24 '11 at 07:50
  • @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. – David Heffernan Apr 24 '11 at 07:57
  • @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. – Remy Lebeau Apr 25 '11 at 19:37
  • 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. – Remy Lebeau Apr 26 '11 at 23:19
  • @Remy In that case, using an explicit cast isn't going to help. Nothing short of fixing the codepage is going to help. – David Heffernan Apr 27 '11 at 02:29
  • 1
    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. – Remy Lebeau Apr 28 '11 at 09:32
  • @remy so you are asserting that explicit cast changes the meaning of the code? Are you sure? – David Heffernan Apr 28 '11 at 11:48
  • 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. – Remy Lebeau May 05 '11 at 07:00
  • Crikey, this is hilarious! Where's Andreas! – Sam Jun 06 '13 at 04:28
4
var
  s: AnsiString;
  w: WideString;
  p: PAnsiChar;
...
  s := p;
  w := WideString(s);
robmil
  • 312
  • 2
  • 4
2

s:PAnsiChar;

WideString(AnsiString(s));

Or on unicode Delphi's you probably want:

String(AnsiString(s));
Wouter van Nifterick
  • 23,603
  • 7
  • 78
  • 122
1

Look for StrPas function in docs.

Eugene Mayevski 'Callback
  • 45,135
  • 8
  • 71
  • 121
  • 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: http://www.freepascal.org/docs-html/rtl/strings/strpas.html – Wouter van Nifterick Apr 24 '11 at 07:45
  • @Woulter now re-read the question. It was not about FPC. So your opinion is completely subjective and ungrounded. – Eugene Mayevski 'Callback Apr 24 '11 at 08:21
  • I didn't vote this down though. StrPas() probably does the job in most cases, but recommending it is something else... – Wouter van Nifterick Apr 24 '11 at 08:25
  • 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. – David Heffernan Apr 24 '11 at 08:27
  • By the way, take a look at StrPas itself in Delphi7: `function StrPas(const Str: PChar): string; begin Result := Str; end;`. – Wouter van Nifterick Apr 24 '11 at 08:29
  • @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). – Eugene Mayevski 'Callback Apr 24 '11 at 08:31
  • 1
    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. – David Heffernan Apr 24 '11 at 08:36
  • delphi prism argument doesn't work for me. Where would you get a PAnsiChar from in .net? – David Heffernan Apr 24 '11 at 08:38