2011-04-13 96 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