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鍵值,可是讀不出。
一、首先往tPing.ini中寫數據
host := '8.8.8.8';
WritePrivateProfileString(
'Host', 'Address',
PChar(host), 'tPing.ini');
發現C:\WINDOWS\tPing.ini文件中已成功寫入以下內容:
[Host]
Address=8.8.8.8
二、讀取數據
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數組是能夠的.ide

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 !不然將會出現錯誤.this

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;spa

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); -- 釋放空間固然是以地址來傳遞的。

相關文章
相關標籤/搜索