delphi pchar char byte string转换问题

delphi pchar char byte string转换问题

注:Delphi中的Char,PChar,PByte,Byte,String的相互转换,您是不是也遇到过,为此头疼过吗?你要是明白了他们的原理就会轻松了。

话题064840的标题是: Q:关于PChar的用法 (200分)

分类:非技术问题 PTiger (1998-10-19 18:33:00)

我要从tPing.ini中读取Host段中的Address键值,但是读不出。

1、首先往tPing.ini中写数据

host := '8.8.8.8';

WritePrivateProfileString(

'Host', 'Address',

PChar(host), 'tPing.ini');

发现C:\WINDOWS\tPing.ini文件中已成功写入如下内容:

[Host]

Address=8.8.8.8

2、读取数据

var

pAddress: PChar;

str: String;

acAddress: array[0..20] of Char;

GetPrivateProfileString(

'Host', 'Address', '127.0.0.1',

pAddress, //这里改为PChar(str)也不行,用acAddress可以

20, 'tPing.ini');

但用就acAddress可以,不知为何?请问PChar与Char数组、String的用

法有何区别?如果用PChar和String,分别如何实现?

请赐教!先说谢了!

tqz (1998-10-19 18:38:00)

你这里的pAddress还没有分配内存呢!

在GetPrivateProfileString前面加入:

pAddress:=StrAlloc(20);

使用完pAddress之后要释放掉:

StrDispose(pAddress );

曹晓钢 (1998-10-19 18:46:00)

或许这是你想要的:

var INI:TINIFile;

begin

INI:=TiNIFile.create('c:\tPing.ini');

INI.ReadString('HOST','Address','0.0.0.0');

定义是:

function ReadString(const Section, Ident, Default: string): string;

procedure WriteString(const Section, Ident, Value: string);

dwwang (1998-10-19 18:49:00)

PChar是指针,这一点上与C相同,因此你要使用(写)

它,必须事先申请内存.你的程序直接用pchar,

没有申请内存,因此肯定不行;相反,char数组是可以的.

pchar与char数组可以直接转换,例如:你的程序里先写:

pAddress:=@acaddress,然后再使用pAddress就可以成功了.

或者用tqz的方法直接分配内存是一样的.

StrPas和StrPCopy可以用来转换pchar与string,

在你的程序里,读出数据后,用str:=strpas(pAddress)

转换就可以了.

O_O (1998-10-20 0:59:00)

不知你用的Delphi是多少版本,2.0以上,将str定义为AnsiString,则可用pchar转换

柳五公子 (1998-10-22 14:17:00)

1. String是Pascal使用的字符串格式.它分为ShortString,

WideString和AnsiString,String缺省为AnsiString.

ShortString的最大长度为255个字符.

AnsiString 的最大长度为2^31个字符.

WideString 的最大长度为2^30个字符.

AnsiString和WideString的区别在于字符集的不同.

AnsiString对应于AnsiChar,WideString对应于WideChar.

具体你可以参考Delphi Help中String Type帮助.

2. PChar是Delphi为了和C语言的字符串类型(char *)兼容,

以便调用Windows API而建立的数据类型.所以pchar实际是

一个指针.一般使用方法是:

pchar eg1;

GetMem(eg1,Size); //你程序中出错就是因为没有为它分配内存

...

FreeMem(eg1,Size);

你还可以用以下方法;

eg2 :array[0..Size] of char;

然后可以把eg2看作pchar来用,且它已预先分配了内存.

要注意的是定义eg2的字符数组下界必须是0 !否则将会出现错误.

3. 在Delphi 1.0中的String和PChar的相互转换为:

function StrPas(str :pchar):string;

function StrPCopy(Dest:Pchar;Source:string):pchar;

在Delphi 2.0和更高版本中的String和PChar的相互转换很简单:

String ->Pchar: pch :=Pchar(str) ;

Pchar ->String: str :=pch;

4. String和pchar的内存实现方法略有不同(虽然他们实际上都是指针),

所以你的例程中不能用pchar(str)来将返回值强制放入str中,而要首先

用一个pchar型变量获得返回值(首先需为其分配内存),然后用

str:=pAddress转换为string型放入str中.

###

aimingoo (1998-10-23 8:05:00)

天啊!!这个问题居然还没有收场???我本来这些天不打算在这儿回答问

题,因为我在做我的MainPage,更糟糕的是,我的系统受到网络Hacker攻击,

Format C:了。忙于整理系统的时候,还是被这200分给吸引了,毕竟,有银

子可拿是无比爽快的事啊!

======================================

1. 如果你的确可以用 acAddress: array[0..20] of Char;来传参数,那

么就可以肯定,你没有为pChar分配内存。

2. GetPrivateProfileString()的第四个参数是lpReturnedString,用于

返回结果串。如果你没有给这个LPTSTR(Delphi中用pChar)分配内存,则返

回为空,如果分配内存不足,将导致结果串不全。

3. 问题是为什么呢?pChar的定义只是一个Pointer!!这意味着,除一个地

址外,pChar本身不用于存放任何东西,也不存放字符串。要不你用sizeof(pChar)

看看就明白了。那可只有4个byte呀!!

4. 那么,pChar的字符串在那儿呢?它事实上被存放在以pChar指向的一个

不定长内存块中。以#0为这个串的结束标志。如果没有特殊指定,Windows

只在找到#0时就认为串结束,而不会如得到一个你所期望的字符串。

5. 我们致少有以下三种解决方法:

(1)在使用pAddress前分配内存,使用后释放内存。

StrSize := 20;

GetMem(pAddress,StrSize);

... //GetPrivateProfileString()调用

FreeMem(pAddress,StrSize);

(2)使用字符数组

const StrSize = 20;

var pAddress : pChar;

chrArr : Array [0..StrSize] of Char;

begin

...

pAddress := @chrArr;

... //GetPrivateProfileString()调用

end; //这种用法中,Delphi会自动释放掉chrArr所用内存

(3) 直接使用字符串

在Delphi 3及以上版本中,支持Huge String,你可以直接将String

用成pChar(D2是否可以,我没有试过)。但是,你也要先给String指定一个长度。如下:

var sAddress : String;

StrSize : Integer;

begin

StrSize := 20;

SetLength(sAddress,StrSize);

GetPrivateProfileString('Host', 'Address', '127.0.0.1',

pChar(sAddress), StrSize, 'tPing.ini');

end;

6. 关于建议:

在上述三种方法中,第一种最安全,第三种是最方便的(因为你可以有一个

动态的buffer,并且,可以象String一样方便的用它),我推荐使用第三种方法。

WritePrivateProfileString()中的使用同上。但如果你采用第三种方法,

则只需要将字符串写到Host串中,用pChar(Host)作为入口参数就成了。不需要

再用SetLength()来指定串长。

使用第三种方法如果编译时提示字符串类型转换错误,则是因为你没有将"Huge

String"编译选项打开,可使用{$H+}编译符指定,或设置Project的Option

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

在delphi中Char,PChar,PByte,Byte,String的相互转换示例:

var

s:string;

pc:pchar;

pb:pbyte;

ac:array[1..100] of char;

ab:array[1..100] of byte;

i:integer;

begin

s:='this is a test';

pc:=pchar(s); //string->pchar

pb:=pbyte(pc); //pchar->pbyte

for i:=1 to length(s) do

begin

ac[i]:=s[i]; //string->arrary of char

ab[i]:=byte(s[i]); //string->arrary of byte

end;

s:=pc; //pchar->string

s:=string(pb); //pbyte->string

s:=c; //arrary of char->string;

end;

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

barton:

虽然这个问题很简单,但其实很不人并不完全清楚。

1.ShortString最大长度是由程序员指定的,但最多255个字符是不错。问题

是Delphi在处理时有很大不同。ShortString可以用Str[0]取字符串长。在

申请局部变量或者传递参数时ShorString在堆栈段分配空间,而其它类型的

串是在堆中;如:MyStr: string[48];在堆栈段分配52字节空间存放一个短

串。

2.String分配和释放由Delphi去优化,你不用关心是否会造成内存泄漏。在每

一个String变量前都有详细的RTTI去管理它。AnsiString和WideString其实

和String在使用时是一样的,因为Delphi并未为AnsiString和WideString建

立特殊的函数。传递参数时是一个地址。例如将流中的数据读到一个String

中,应该按下列方式操作:

SetLength(Result, Count); //相当于分配空间

Stream.Read(Result[1], Count); //读数据到串

3.PChar类型纯粹为兼容C和WindowsAPI而设,使用非常麻烦。

APChar := StrAlloc(n); -- 分配空间

StrDispose(APChar); -- 释放空间

当然是以地址来传递的。