TStringList .add从随机函数生成重复项

时间:2011-07-14 21:32:53

标签: delphi for-loop freepascal tstringlist

遇到问题我似乎无法指责。我试图从函数调用中收集字符串(带字母和数字的随机代码)并放入我的TStringList变量中。相关代码如下。

如果我进行测试,字符串会重复一段时间,然后会生成一个新字符串。如果我在每次生成代码后引入sleep(xx)或showmessage命令(请参阅下面的'edits'),它会复制/返回memo罚款,一切看起来都很好。如果我删除'延迟',我会再次从函数中重复。

要添加到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是一个函数,用于返回单个随机字符串的字符+数字(A..Z a..z 0..9)。它可以自行运行。

(编写答案2)

没有例外。

因此,如果我不包含sleep(),它可能会生成500个字符串,但它们都是重复的;经过一段时间后它确实发生了变化。当我增加睡眠命令时,函数调用的重复次数减少。在睡眠周围(40);它从功能上正确显示。但当然这是耗时且不可接受的。

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;

3 个答案:

答案 0 :(得分:4)

这是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 documentation

  

不要将循环中的Randomize调用与调用   随机功能。通常,Randomize在所有之前只调用一次   调用随机。

答案 1 :(得分:0)

没有看到MakeCode()实际在sResult中返回的内容,我的猜测是sResult包含导致备忘录甚至RTL的不可打印的控制字符(特别是空字符)跳过子序列字符。

答案 2 :(得分:0)

您需要显示更多代码,evtl。 MakeCode。我会尝试使用没有MakeCode的sResult中的常量String,你会得到相同的吗?尝试类似的事情:

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;

你有任何例外吗?