[英]TStringList .add produces duplicates from random function
遇到問題,我似乎無法解決問題。 我正在嘗試從 function 調用中收集字符串(帶有字母和數字的隨機代碼)並放入我的 TStringList 變量中。 相關代碼如下。
如果我運行測試,字符串會重復給定的時間,然后生成一個新的。 如果我在每次生成代碼后引入 sleep(xx) 或 showmessage 命令(請參閱下面的“編輯”),它會很好地復制/返回到備忘錄,一切看起來都很好。 如果我刪除“延遲”,我會再次從 function 得到重復。
function 添加到 TStringList 的部分:
..
AddToMemo:=TStringList.Create;
AddToMemo.Clear;
AddToMemo.Sorted:=False;
for loop := 1 to totalamount do
begin
sResult:=MakeCode(charspercode, cbUpperLowerCase, cbAvoidChars, customchars);
Sleep(50);
// (or):
//ShowMessage(sResult);
// ^ If I leave a Sleep or ShowMessage in, I can see sResult just fine and
// program works fine - results in memo are correct as well. If I remove
// it, I get repeated entries.
AddToMemo.add(sResult+IntToStr(loop));
// If I remove "sResult+" from AddToMemo.add the ".add"
// works - shows loop numbers in my updated memo
// If left in, I see one code (1st one produced) and no
// appended number at all in Memo produced.
end;
Result:=AddToMemo;
end;
編輯:正如我在下面提到的,如果我留下 ShowMessage 或 Sleep(xx) 調用以在.add 之間暫停,它工作正常。 如果我刪除它,我會在最終的 tmemo 中得到一堆重復的條目。 編輯: MakeCode 是一個 function 返回一個隨機的字符+數字字符串(A..Z a..z 0..9)。 它自己工作得很好。
(編輯答案2)
沒有出現異常。
因此,如果我不包括 sleep() 它可能會生成 500 個字符串,但它們都是重復的; 在給定的時間后,它確實發生了變化。 function 調用的重復次數隨着我增加睡眠命令而減少。 在睡眠(40)左右; 它從 function 正確顯示。 但當然,這是耗時且不可接受的。
MakeCode() 的“膽量”
function MakeCode(CharsPerCode: Integer; bULCase, bAvoidChars: Boolean; sCChars: String): String;
var
i: integer;
s: string;
begin
//(misc stuff here)
begin
randomize;
s[0]:=chr(CharsPerCode);
for i:=1 to CharsPerCode do
repeat
s[i]:=chr(random(128));
until
(s[i] in ['A'..'Z','a'..'z','0'..'9'])
end;
Result:=s;
end;
這是Randomize
的一種行為。 隨機數發生器通過對系統時鍾的計算進行初始化。 如果您在快速循環中的每次迭代中調用它,它將使用相同的種子進行初始化。 這就是Sleep(50)
改變結果的原因。 例如,在開始填充字符串列表之前調用一次 randomize。
...
AddToMemo.Clear;
AddToMemo.Sorted:=False;
Randomize; // <-- possibly here
for loop := 1 to totalamount do
...
function MakeCode(CharsPerCode: Integer; bULCase, bAvoidChars: Boolean; sCChars: String):
...
begin
// randomize; // <-- not here!
s[0]:=chr(CharsPerCode);
以下引用來自Delphi 文檔:
不要將循環中對 Randomize 的調用與對 Random function 的調用結合起來。 通常,在對 Random 的所有調用之前,僅調用一次 Randomize。
在沒有看到 MakeCode() 實際上在sResult
返回什么的情況下,我的猜測是sResult
包含不可打印的控制字符(特別是空字符),導致備忘錄甚至 RTL 跳過子序列字符。
您需要顯示更多代碼,evtl。 制作代碼。 在沒有 MakeCode 的情況下,我會在 sResult 中使用常量字符串嘗試相同的操作,你得到相同的結果嗎? 嘗試類似:
for loop := 1 to totalamount do
begin
try
sResult:=MakeCode(charspercode, cbUpperLowerCase, cbAvoidChars, customchars);
AddToMemo.add(sResult+IntToStr(loop));
except on e: exception do
showmessage(e.message);
end;
end;
你有任何例外嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.