因为要调用windows的api或者给vc++写接口,很多地方都要用到pchar,现在将char数组、string和pchar之间的相互转换都列出来,都是网上找的资料,我总结一下,先直接上代码,再讲原理。

1.string转换成pchar

可以使用pchar进行强制类型转换,也可以使用StrPCopy函数

var
s:string;
p,p1:PChar;
begin
s:='Hello Delphi';
p:=PChar(s);
ShowMessage(p);
p1:=StrAlloc(Length(s)+);
StrPCopy(p1,s);
ShowMessage(p1);
StrDispose(p1);
end;

2.pchar转换成string

pchar可以直接当string用,也可以用strpas函数转换一下

var
s,s1,s2:string;
p:PChar;
begin
s:='Hello Delphi';
p:=PChar(s);
ShowMessage(p);
s1:=p;
ShowMessage(s1);
s2:=StrPas(p);
ShowMessage(s2);
end;

3.char数组转换成string
   使用StrPas函数获取数组的首地址

var
c:array [..] of Char;
s:string;
begin
c[]:='H';
c[]:='e';
c[]:='l';
c[]:='l';
c[]:='o';
c[]:=' ';
c[]:='D';
c[]:='e';
c[]:='l';
c[]:='p';
c[]:='h';
c[]:='i';
s:=StrPas(@c[]);
ShowMessage(s);
end;

4.string转char数组

使用move或者copymemory函数

var
s:string;
c:array of Char;
i:Integer;
begin
s:='Hello Delphi';
SetLength(c,Length(s));
//Move(s[1],c[0],Length(s));//move和CopyMemory都行
CopyMemory(@c[],PChar(s),Length(s));
for i:=Low(c) to High(c) do
begin
ShowMessage(string(c[i]))
end;
end;

5.char数组转pchar

var
c:array [..] of Char;
p:PChar;
begin
c:='Hello Delphi';
//p:=@c[0];
p:=PChar(@c[]);
ShowMessage(StrPas(p));
end;

6.pchar转char数组

使用move或者CopyMemory函数

var
s:string;
p:PChar;
c:array of Char;
i:Integer;
begin
s:='Hello Delphi';
p:=PChar(s);
SetLength(c,Length(s));
//Move(p^,c[0],Length(s));//move和CopyMemory都行
CopyMemory(@c[],p,Length(s));;
for i:=Low(c) to High(c) do
begin
ShowMessage(string(c[i]))
end;
end;

现在讲讲char数组、pchar和string

string和Char数组都是一块内存,其中存放连续的字符. string保存具体字符的内存对用户是透明的, 由Delphi管理它的分配, 复制和释放, 用户不能干预(其实也可以, 不过是通过非法途径). Char数组就不必说了吧?PChar是一个指针, 它的大小只有32位. 定义时由Delphi自动填0. 要将PChar作为字符串使用的话必须自己分配内存用完必须自己释放. PChar型字符串由#0表示字符串结尾Delphi所提供的相关PChar字符串的操作都是判断#0来决定字符串的结尾的。
因为PChar是指针,所以它能指向任何地方(也就是说它不一定非要指向字符串不可).把一个String赋值给PChar只是将String中保存具体字符串的内存的地址给PChar变量. 当然也可以把Char数组第一个元素的地址给PChar.

至于 哪个占用内存小, Char数组<PChar(指分配过字符串的)<string(除了具体字符串外还包含字符串长度)
如果空字符串那么PChar<String<array [0..n] of Char
从速度来说毫无疑问string最慢, 例如:
作为参数传递(非var调用时)给过程时string将整个字串的副本传递过去, PChar将指针本身的副本传递过去(32位), Char数组和PChar一样, 传递的是第一个元素的地址副本.不过就灵活性来说string最高, 而且Delphi支持的函数最多. 另外可以将String作为Buffer使用(因为它当中可以包含字符0).

注:因为string和char数组都是连续的,所以指向string的首地址的指针为@s[1],指向char数组的首地址的指针为@c[0]。pchar是以#0结尾的,所以很多关于pchar

的函数的使用的时候要注意,如使用StrAlloc函数给pchar分配内存的时候和使用StrPCopy函数的时候

7.使用StrAlloc函数将一个string转换给pchar

var
p:PChar;
s:string;
begin
s:='ABCDEF';
p:=StrAlloc(Length(s));
Move(s[],p^,Length(s));
ShowMessage(StrPas(p));
StrDispose(p);
end;

执行以上代码的时候,字符串后面有乱码,查看delphi帮助里面关于StrAlloc函数

delphi的帮助如下:

StrAlloc allocates a buffer for a null-terminated string with a maximum length ofSize - 1 (1 byte must be reserved for the termination character).

StrAlloc函数给pchar指向的字符串分配的实力内存为size-1个字节,所以我们要多分配一个字节的内存,用来存pchar的结束标志#0

正确使用如下:

var
p:PChar;
s:string;
begin
s:='ABCDEF';
p:=StrAlloc(Length(s)+);
Move(s[],p^,Length(s)+);//将s的内容按照字节复制到p里面
//Move(s[1],p^,Length(s)); //执行这句会出现乱码
ShowMessage(StrPas(p));
StrDispose(p);
end;

8.使用StrPCopy将string转换成char数组

var
s:string;
c:array of Char;
i:Integer;
begin
s:='Hello Delphi';
SetLength(c,Length(s));
StrPCopy(@c[],s);
for i:=Low(c) to High(c) do
begin
ShowMessage(string(c[i]))
end;
end;

以上代码执行的时候会报错,查看delphi帮助才知道,strpcopy函数不做长度检查,需要程序员自己控制。

delphi帮助如下:

StrPCopy copies Source into a null-terminated string Dest. It returns a pointer to Dest.
StrPCopy does not perform any length checking. 
The destination buffer must have room for at least Length(Source)+1 characters

正确代码如下:

var
s:string;
c:array of Char;
i:Integer;
begin
s:='Hello Delphi';
SetLength(c,Length(s)+);
StrPCopy(@c[],s);
for i:=Low(c) to High(c) do
begin
ShowMessage(string(c[i]))
end;
end;

使用strpcopy函数的时候一定要保证目的pchar的长度至少是源字符串的长度+1

delphi char数组、string和Pchar的相互转换的更多相关文章

  1. c++中char*\wchar_t*\string\wstring之间的相互转换

    string U2A(const wstring& str)//Unicode字符转Ascii字符 { string strDes; if ( str.empty() ) goto __end ...

  2. Delphi中的各种字符串、String、PChar、Char数组

    参考博客:http://www.cnblogs.com/pchmonster/archive/2011/12/14/2287686.html 其中的所有代码均在Delphi7下测试通过. Delphi ...

  3. PChar,PAnsiChar,String,AnsiString,Char数组,AnsiChar数组转换

    PChar,PAnsiChar,String,AnsiString,Char数组,AnsiChar数组之间的转换关系见下图 通过转换链,可以实现任意两个类型之间的互转.如PChar转PAnsiChar ...

  4. C#字符串与char数组互转!

    字符串转换成Char数组string str="abcdefghijklmnopqretuvwxyz";char[] chars=str.ToCharArray(); char数组 ...

  5. C++ char*,const char*,string,int 的相互转换

    C++ char*,const char*,string,int 的相互转换   1. string转const char* string s ="abc";const char* ...

  6. CHAR数组转成STRING:C++

    有些时候,键入了CHAR数组却不会知道到底有多长,是不是很差评呢?但是,转成STRING就可以啦QWQ #include <iostream> #include <cstdio> ...

  7. char数组和String互转

    char ch[100];string str; 把char*(c类型的string)数组转换为string:str = ch; //即可str.assign(ch); //也可 把string类型转 ...

  8. Java中char和String的相互转换

    转自:http://blog.csdn.net/yaokai_assultmaster/article/details/52082763 Java中char是一个基本类型,而String是一个引用类型 ...

  9. (c++) int 转 string,char*,const char*和string的相互转换

    一.int 和string的相互转换 1 int 转化为 string c++ //char *itoa( int value, char *string,int radix); // 原型说明: / ...

随机推荐

  1. EasyUI 分页 简洁代码

    做分页代码,看到网上很多人实现的方法,那是各种调用,各种获取对象.我很不解,因为Easyui已经给我们了分页的具体实现,为什么有些人要画蛇添足呢. 其实真正的分页,在你的代码中,别人可能都没有注意到, ...

  2. WPF禁止拖拽窗口到边缘自动最大化

    近期有个需求,可以通过拖拽改变窗口大小,但是不允许窗口最大化.最小化.拖到边缘的时候也不能自动最大化. 要想禁止拖拽窗口到边缘自动最大化,只要改注册表即可,但是系统所有应用都会被禁止. 1.运行reg ...

  3. optimizer_switch引起的诡异问题

    参数描述 MySQL中不同的版本优化器会有很多新特性,比如MRR.BKA等,optimizer_switch这个参数就是控制查询优化器怎样使用这些特性.很多情况下我们会根据自身的需求去设置optimi ...

  4. MySQL LOCK TABLES 与UNLOCK TABLES

    http://blog.csdn.net/zyz511919766/article/details/16342003 1语法 LOCK TABLES tbl_name[[AS] alias] lock ...

  5. Java crash问题分析

    Java的应用有时候会因为各种原因Crash,这时候会产生一个类似java_errorpid.log的错误日志.可以拿到了 这个日志,怎样分析Crash的原因呢?下面我们来详细讨论如何分析java_e ...

  6. kbmmw 中的日期时间操作

    为了精确度反映时间及时区,kbmmw 里面专门有一个单元处理日期时间,由于很多同学习惯了delphi 自带的Tdatetime,使用这个时会有一些疑惑,因此今天就单独说一下这个. 首先kbmmwdat ...

  7. kbmmw 中XML 操作入门

    delphi 很早以前就自带了xml 的操作,最新版里面有三种XML 解释器,一种是MSXML,看名字就知道 这个是微软自带的,这个据delphi 官方称是速度是最快的,但是只能在windows 上使 ...

  8. Oracle服务器修改IP后

    机房有两套网络,一套办公网,一套机房的内网,办公网可以通过vpn在其他地方访问,内网只能在公司办公室访问.团队有同事去外地办公,开发的时候需要通过客户端直连数据库,于是把数据库服务器的网线换到办公网的 ...

  9. mac os下提高android studio运行速度终极方法

    /Users/hangliao/ 删除(.android  .gradle)两个文件夹 android studio恢复所有设置到初始化状态,这样会删除已创建的模拟器,所以需从创建一下模拟器 mac ...

  10. (5)How to let go of being a "good" person — and become a better person

    https://www.ted.com/talks/dolly_chugh_how_to_let_go_of_being_a_good_person_and_become_a_better_perso ...