1

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

如果我运行测试,字符串会重复给定的时间,然后生成一个新的。如果我在每次生成代码后引入 sleep(xx) 或 showmessage 命令(请参阅下面的“编辑”),它会很好地复制/返回到备忘录,一切看起来都很好。如果我删除“延迟”,我会再次从功能中重复。

添加到 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;
4

3 回答 3

4

这是 的一种行为Randomize。随机数发生器通过对系统时钟的计算进行初始化。如果您在快速循环中的每次迭代中调用它,它将使用相同的种子进行初始化。这就是为什么 aSleep(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 函数的调用结合使用。通常,在对 Random 的所有调用之前,仅调用一次 Randomize。

于 2011-07-17T19:56:25.187 回答
0

您需要显示更多代码,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;

你有任何例外吗?

于 2011-07-15T06:20:47.000 回答
0

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

于 2011-07-14T21:47:02.677 回答