From: mliesen@netg.se (Martin Liesen)
Subject: Re: [delphi] Problems with PChar
Date: Tue, 13 Jun 1995 00:59:18 +0200

Working with PChar is quite similar to char* in C, this will not neccessary
help you, so I'll try to expand !

(s:string, p:pchar in all examples)

To use pchar you always must allocate some sort of memory where to perform
the operations. Either you are given the memory by a called funtion, or a
memory block defined i compilation-time (in stack or in the global data
memory), or you must allocate it from the operating system (my personal
favorit).
A few exampel of how this can be done;

1) --- use heap memory (perhaps the best method)
        procedure test;
        var p:pchar;
        begin
                p:=stralloc(20);                { can hold 19 characters }
                ....
                strdispose(p);                  { release memory again }
        end;

2) --- use stack (or data, if defined global) memory

    { #A  -  orginal, easy to understand }
        procedure test;
        var ch:Array[0..19] of char;
        begin
                p:=@ch[0];
        end;
        
    { #B  -  as a constant, will automaticly be #0 - terminated }
        const
                a_pchar:pchar='any thing you like';

    { #C  -  make a string to a pchar, using string's allocated memory }
        procedure test;
        var s:string;
        begin
                s:='this is a test';
                s:=s+#0;                { makes string null -terminated }
                p:=@s[1];               { skip s[0], as it contains length
info }         end;
        

.. serveral other methods.


-------------------

To use the pchars, you mostly work in a simular way as with String, but
using other function/procedure calls.

strpos - pos
strlen - length

Operations are REALY different, they MUST be performed by function calls.

s:='this is a string';

        use:    strnew          - allocates new memory for copy
                strcopy         - you suply a memory where to place copy
                strLcopy        - as strcopy, but gives you the possibility
                                  to avoid copying 789 characters to you
                                  512 bytes buffert (=crash).

if s=s2 then

        use:    strcomp         - just as easy,   "if strcomp(s,s2) then"
                strIcomp        - same as above, none case sensitiv.

s:=s+s2;

        use:    strcat          - add another pchar to the end of one.
                strLcat         - as strcat, (compare with strLcopy)

You can find information about every singel function in the online manuals.

--------------------------

Often you will have to make a string to a pchar, or the other way around;

(pchar -> string )
s:=strpas(p);

(string -> pchar #1 )
strPcopy(p,s);  { also strPLcopy is available, p must have allocated mem }

(string -> pchar #2 )
s:=s+#0;
p:=@s[1];

----------------------------------

The reason why why you had to use special functions to perform such basic
tasks as compare & setting of pchars is because, pchar is pointers, and
operations on pchar will be pointer-operations!

Say p points to an area containing 'hello world'#0, if you perform
p:=p+3;   p would point to 'lo world'#0.   As most functions returs a new
pchar pointer (i.e strpos) to a location inside your memory, this can be
very usefull, i.e;

If you wish to know how many character there is in '12345'#0 before the '4'
you could not just use strpos, as it would return a pointer to the '345'#0,
you would have to do something like this;   no_chars_befor_4 :=
strpos('4',p) -p;


This kind of operations can not be performed on string,   s:=s+1,  would
generate a nice compiler error.   These pointer-operations is why pchar a
very nice tool working with parsing tasks. Also it's almost much less
restricted size (<64Kb, due to Delphi MemAlloc word size format, <64Kb due
to DOS getmem limitation) makes it very attractive.


-----------------------

Hope this will help you a bit   (also hope I mostly told you the truth)

Martin Liesen, PegaSoft
