2011-04-13 191 views
3

我想从我的字符串的开头删除每个字符,这不是一个字母。使用Delete()时访问冲突00000000;

但是,当字符串中只有非字母字符(如“!!”或“?!?”)时,它会吐出一个Access Violation!

这里是我的代码:

// The Log(); is a routine that adds stuff to my log memo. 
    Log('Begin Parse'); 
    while not IsLetter(ParsedName[1]) do 
    begin 
    Log('Checking Length - Length is '+IntToStr(Length(ParsedName))+' ...'); 
    if Length(ParsedName) <> 0 then 
    Begin 
    Log('Deleting Char ...'); 
    Delete(ParsedName,1,1); 
    Log('Deleted Char ...'); 
    End; 
    Log('Checking Length - Length is now '+IntToStr(Length(ParsedName))+' ...'); 
    end; 
    // It never reaches this point! 
    Log('End Parse'); 

这是我的日志产生:

21:51:19: Checking Length - Length is 2 ... 
21:51:19: Deleting Char ... 
21:51:19: Deleted Char ... 
21:51:19: Checking Length - Length is now 1 ... 
21:51:19: Checking Length - Length is 1 ... 
21:51:19: Deleting Char ... 
21:51:19: Deleted Char ... 
21:51:19: Checking Length - Length is now 0 ... 
21:51:19: Access violation at address 007A1C09 in module 'Project1.exe'. Read of address 00000000 

正如你看到的,它发生之后的所有字符已被删除。我假设问题在于,不知何故,我试图访问不在那里的东西,但如何我正在这样做,我看不到。

编辑:是的,我知道这是一个愚蠢的问题和所有的东西 - 我只是监督一些东西。不要告诉我doesen不会发生在你身上;)

+4

@Jeff,当你添加日志记录进行故障排除的伟大。但是,如果您要添加日志记录代码,则应该学会实际读取日志条目。你的问题的答案在你的日志的最后一行显而易见:“21:51:19:检查长度 - **长度现在是0 ** ...”。显然,如果长度现在为0,则访问ParsedName [1]将失败,因为不再有ParsedName []。 – 2011-04-13 20:39:49

+7

如果您打开了**范围检查**,那么访问冲突永远不会发生。转到您的编译器选项并立即打开它。然后,永远不要关闭它。与节省您的故障排除时间相比,程序运行所花费的额外时间可以忽略不计。 – 2011-04-13 20:55:49

+1

除了Ken的评论之外,更仔细地阅读日志也会告诉你,你没有理由得出结论Delete是罪魁祸首,因为你的程序在调用它之后能够记录另外两条消息。问题出现在“现在的长度”消息和“长度是”或“结束分析”消息之间。这些之间唯一的事情就是IsLetter,所以在那里设置一个断点,看看你是否可以弄清楚为什么它会在你迭代的ParsedName的特定值上崩溃。 – 2011-04-13 21:00:01

回答

13

这个问题与Delete无关。即使您告诉它删除不存在的字符,删除仍然有效。

线

while not IsLetter(ParsedName[1]) do 

试图访问ParsedName[1],所以这个角色有更好的存在。你的代码是不是特别漂亮,但一个简单的解决方法是

while (length(ParsedName) > 0) and not IsLetter(ParsedName[1]) do 

你可以做到这

while (length(ParsedName) > 0) and not IsLetter(ParsedName[1]) do 
    Delete(ParsedName, 1, 1); 
+0

正是我需要的 - 谢谢! '你的代码不是特别漂亮'出于兴趣,你会怎么做? – Jeff 2011-04-13 20:05:35

+0

此外,我添加删除的原因,是因为我认为这是所有这一切搞砸了。 – Jeff 2011-04-13 20:07:10

+0

查看SysUtils中的修剪代码,并使用IsLetter(..)执行相同的操作 - 速度也更快。 – Edelcom 2011-04-14 03:58:10

3

你也希望在While测试中加入一个检查字符串长度是否大于0的检查。

您正在检查if语句之前是否为数字来检查字符串的长度。或者,您可以将字符串长度检查移至删除角色后的位置。然而你想要这样做:)

+0

我相信我已经做到了 - '如果长度(ParsedName)<> 0 then' – Jeff 2011-04-13 20:00:59

+0

是的,我刚更新了答案以指定它需要的地方。对不起,关于:) – James 2011-04-13 20:02:40

+0

所以我不这样做的权利?您介意修改我的代码以反映您的更改吗?谢谢! :) – Jeff 2011-04-13 20:03:34