簡體   English   中英

TStringList.add 從隨機 function 生成重復項

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM