遇到问题我似乎无法指责。我试图从函数调用中收集字符串(带字母和数字的随机代码)并放入我的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;
答案 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;
你有任何例外吗?