delphi7 PChar 转为 String 弹出乱码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了delphi7 PChar 转为 String 弹出乱码相关的知识,希望对你有一定的参考价值。

delphi7 PChar 转为 String
弹出乱码

StrPas(String)
有知道的吗?
StrPas(这里是pchar类型)

你传进函数的参数必须是个已经分配内存(这是你编写程序该做的),并且在该内存区域内有以0结尾的字符串指针(若字符串是空的,首字节必须为0值),然后才能保证StrPas()调用没问题,否则,出现乱码还是好的呢,引发异常也是可能的。 参考技术A var
str :string;
p :PChar;
begin
str := 'Hello world ';
p := PChar(str);

ShowMessage(p); // pchar 可以当 string 用
end;
参考技术B PAnsiChar

delphi char数组string和Pchar的相互转换

因为要调用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)+1);
  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 [0..11] of Char;
  s:string;
begin
  c[0]:=H;
  c[1]:=e;
  c[2]:=l;
  c[3]:=l;
  c[4]:=o;
  c[5]:= ;
  c[6]:=D;
  c[7]:=e;
  c[8]:=l;
  c[9]:=p;
  c[10]:=h;
  c[11]:=i;
  s:=StrPas(@c[0]);
  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[0],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 [0..11] of Char;
  p:PChar;
begin
  c:=Hello Delphi;
  //p:[email protected][0];
  p:=PChar(@c[0]);
  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[0],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[1],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)+1);
  Move(s[1],p^,Length(s)+1);//将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[0],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)+1);
  StrPCopy(@c[0],s);
  for i:=Low(c) to High(c) do
  begin
    ShowMessage(string(c[i]))
  end;
end;

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

以上是关于delphi7 PChar 转为 String 弹出乱码的主要内容,如果未能解决你的问题,请参考以下文章

Delphi7中如何读取或显示Bytes类型的字段

delphi 换版本乱码 问题

delphi char数组string和Pchar的相互转换

delphi7 中如何点击菜单项弹出新窗体

关于PChar(@string)的疑惑

Borland delphi7 安装完之后运行,就马上弹出一个名为“Error”对话框