因为要调用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. Windows 8风格应用-触控输入

    参考:演练:创建您的第一个触控应用程序 http://msdn.microsoft.com/zh-cn/library/ee649090(v=vs.110).aspx win8支持多点触摸技术,而我们 ...

  2. 控制台管理apk

    http://www.cnblogs.com/mythou/archive/2013/06/11/3132249.html pm命令的具体用法如下: pm 命令是Android里面packageMan ...

  3. mysql查看某个表的列名

    mysql查看某个表的列名mysql -uusername -p 输入密码按登录mysqlshow databases; 查看有哪些数据库use dbname; 选择数据库show tables:查看 ...

  4. 2018.12.15 poj3415 Common Substrings(后缀自动机)

    传送门 后缀自动机基础题. 给两个字符串,让你求长度不小于kkk的公共子串的数量. 这题可以用后缀自动机解决废话 考虑对其中一个字串建出后缀自动机,然后用另一个在上面跑,注意到如果一个状态有贡献的话, ...

  5. Eclipse创建Dynamic Web部署

    Eclipse创建Dynamic Web部署 http://blog.csdn.net/sweblish/article/details/6686046 Eclipse3.x中热部署项目,启动错误问题 ...

  6. Java核心技术之基础知识

    一.类型转换 数值类型之间的转换 强制类型转换 a)       将一个数值强制转换成另一种类型时,如果超出目标类型的便是范围,结果就会截断成一个完全不同的值.(如:(byte)300的实际值为44) ...

  7. 20155205 2016-2017-2 《Java程序设计》第2周学习总结

    20155205 2016-2017-2 <Java程序设计>第2周学习总结 教材学习内容总结 变量 变量在命名时有一些规则,它不可以使用数字作为开头,也不可以使用特殊字符. 对常用忽略符 ...

  8. wx.setStorageSync(KEY,DATA)

    wx.setStorageSync 每个微信小程序都可以有自己的本地缓存,可以通过wx.setStorage(wx.setStorageSync).wx.getStorage(wx.getStorag ...

  9. hdu 1716 排列

    题目 这道题是全排列问题,主要注意的是格式问题.觉得下面这种写法最为巧妙 #include <cstdio> #include <iostream> #include < ...

  10. 求n得阶乘得最后一位非零数字

    如题,最后一位数好求,他只和最后一位相乘后的最后一位有关,唯一影响我们得是末尾0,而阶乘中末尾0来自于2和5,(10得话可以看成2 * 5),所以有这个思想我们可以筛选出1 * 2 * 3 * ... ...