全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1216
推到 Plurk!
推到 Facebook!

string 在 object 中存取問題

尚未結案
KFC123_60201
一般會員


發表:58
回覆:18
積分:15
註冊:2006-07-25

發送簡訊給我
#1 引用回覆 回覆 發表時間:2010-03-10 14:53:01 IP:139.78.xxx.xxx 訂閱
我有一個 class,裡面定義了一些簡單的 strings


[code delphi]
PTSentence = ^TSentence;
TSentence = class(TObject)
public
id :Integer;
S1, S2, S3 :String;
procedure setSentence( id :integer; S2, S2, S3 :String );
end;


procedure TSentence.setSentence(id :Integer; S1, S2, S3: String);
var
tmpStr1, tmpStr2, tmpStr3 :PChar;
begin
try
Self.id := id;

tmpStr1 := PChar(S1);
GetMem(tmpStr2, StrLen(tmpStr1) 1);
GetMem(tmpStr3, StrLen(tmpStr1)*2);
Self.S1 := String(tmpStr3);

Self.S2 := S2;
Self.S3 := S3;
finally
FreeMem(tmpStr2);
FreeMem(tmpStr3);
end;
end;

[/code]

我從access database 中讀出每一條記錄,然後生成一個object ,把object記在一個stringlist中備用


[code delphi]
{ 讀取 database }
...
sid := Fields.Fields[0].AsInteger;
S1 := Fields.Fields[1].AsString;
S2 := Fields.Fields[2].AsString;
S3 := Fields.Fields[3].AsString;

sentObj := TSentence.Create; // sentObj 是 TSentence
sentObj.setSentence(sid, S1, S2, S3);
sentenceList.Add(sentObj); // sentenceList 是 TStringList
[/code]

數据存儲到 stringlist 後,以後會被讀出作進一步處理


[code delphi]
sentObj := TSentence(Self.sentenceList.Items[3]); // sentenceList 是 StringList
curSent := sentObj; // curSent 是被讀出的TSentence Object
[/code]

到目前為止似乎沒甚麼問題,但我不明白的是,在 TSentence 的 setsentence 中,為甚麼在處理 S1 的 copy 時要用到GetMem? 而處理 S2, S3 時卻直接 assign? 我的數据庫字段中,S1, S2, S3 是中英文混合的。那段 setsentence 的代碼我是從forum中找到的,我試過,如果寫成下面的方式

[code delphi]
procedure TSentence.setSentence(id :Integer; S1, S2, S3: String);
begin
Self.id := id;
Self.S1 := S1;
Self.S2 := S2;
Self.S3 := S3;
end;

[/code]

則在數据存在 StringList 後被再次讀出時會有亂碼。但如果我對 S2, S3 都用GetMem等方式處理,即

[code delphi]
procedure TSentence.setSentence(id :Integer; S1, S2, S3: String);
var
tmpStr1, tmpStr2, tmpStr3 :PChar;
begin
try
Self.id := id;

tmpStr1 := PChar(S1);
GetMem(tmpStr2, StrLen(tmpStr1) 1);
GetMem(tmpStr3, StrLen(tmpStr1)*2);
Self.S1 := String(tmpStr3);
FreeMem(tmpStr2);
FreeMem(tmpStr3);

tmpStr1 := PChar(S2);
GetMem(tmpStr2, StrLen(tmpStr1) 1);
GetMem(tmpStr3, StrLen(tmpStr1)*2);
Self.S2 := String(tmpStr3);
FreeMem(tmpStr2);
FreeMem(tmpStr3);

tmpStr1 := PChar(S3);
GetMem(tmpStr2, StrLen(tmpStr1) 1);
GetMem(tmpStr3, StrLen(tmpStr1)*2);
Self.S3 := String(tmpStr3);
finally
FreeMem(tmpStr2);
FreeMem(tmpStr3);
end;
end;

[/code]

則再次從 TstringList 中讀取 Object時會出錯。請問怎樣處理才是正確的做法?
編輯記錄
KFC123_60201 重新編輯於 2010-03-10 14:54:30, 註解 無‧
shunaaron
高階會員


發表:13
回覆:94
積分:106
註冊:2006-10-06

發送簡訊給我
#2 引用回覆 回覆 發表時間:2010-03-15 10:32:23 IP:59.124.xxx.xxx 訂閱
ttI : Integer;//指標
ttOrder := POrder(ttStr.object[ttI])
ttMsg := ttOrder.id ;
------
程式沒有這麼難
只是還沒打通其中要絕
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#3 引用回覆 回覆 發表時間:2010-03-15 11:20:23 IP:112.104.xxx.xxx 未訂閱
幾個問題:
(1) function AddObject(const S: string; AObject: TObject): Integer; override;

sentObj := TSentence.Create; // sentObj 是 TSentence
sentObj.setSentence(sid, S1, S2, S3);
sentObj := TSentence(Self.sentenceList.Objects[3]); // sentenceList 是 StringList
curSent := sentObj; // curSent 是被讀出的TSentence Object

(3) 記得在 Free sentenceList 時, 要先Free 自行產生的物件

(4) 字串直接 Assign 即可, 除非宣告於record 中, 且有儲存動作時
應使用 short string 方式.


Ktop_Robot
站務副站長


發表:0
回覆:3511
積分:0
註冊:2007-04-17

發送簡訊給我
#4 引用回覆 回覆 發表時間:2010-03-25 12:31:20 IP:000.000.xxx.xxx 未訂閱
提問者您好:


以上回應是否已得到滿意的答覆?


若已得到滿意的答覆,請在一週內結案,否則請在一週內回覆還有什麼未盡事宜,不然,
將由版主(尚無版主之區域將由副站長或站長)自由心證,選擇較合適之解答予以結案處理,
被選上之答題者同樣會有加分獎勵同時發問者將受到扣 1 分的處分。不便之處,請見諒。


有問有答有結案,才能有良性的互動,良好的討論環境需要大家共同維護,感謝您的配合。

------
我是機器人,我不接受簡訊.
系統時間:2024-05-16 13:59:24
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!