我使用以下方法來移動並操作AnsiString
。它大部分時間都在工作,但有時指向字符串的指針停止工作。考慮下面的代碼:德爾福AnsiString操縱 - PAnsiChar變得腐敗?
var
s: AnsiString;
p: PAnsiChar;
offset, idx, cnt: Integer;
begin
s := 'some>very>long>string>with>field>delimiters>';
p := @s[1];
offset := 1;
// find the 5th field
cnt := 5;
repeat
idx := AnsiString.AnsiPos('>', p);
Inc(p, idx);
Inc(offset, idx);
Dec(cnt);
until cnt = 0;
// insert a new field after the 5th field
Insert(AnsiString('something new>'), s, offset);
// skip other fields
// insert other values
// repeat
end;
調試時,剛過repeat..until
循環結束,你可以看一下檢查,看到p = 'field>delimiters>'
。在檢查員Insert()
聲明後,s = 'some>very>long>string>with>something new>field>delimiters>'
和p = 'something new>field>delimiters>'
。這是預期的。
我的真實字符串是幾千個字符長。這種移動字符串並添加新字段的方法可以運行數十次,然後突然停止工作。在調用Insert()
後,p
不再顯示字符串前面的插入值。 p
似乎不知道s
已經改變...
爲什麼p
正確地引用一個字符上s
最Insert()
語句後,突然停止了一些呼籲Insert()
後的工作?
(我發現了回答我的問題,打字時不起來。現在答案似乎是顯而易見的,但不能因此而我這個問題掙扎。也許張貼問題和答案將幫助別人......)
只是供參考:在你的問題和你的答案中,你永遠不會在循環中使用它之前初始化'offset'。因此,您將隨機存儲器內容開始,並且每次通過循環時用'idx'的值遞增。 – 2013-02-22 02:47:55
如果存在,您真正可以使用的是「AnsiPosEx」,這是一個將AnsiPos的MBCS感知與PosEx的可配置開始索引相結合的函數。那麼你根本就不需要'p',那麼每次你傳遞'p'作爲期望AnsiString的參數並且編譯器自動完成自動轉換時,就可以節省你創建和銷燬幾千個字符長的字符串您。如果您的搜索字詞確實是一個字符,請考慮使用AnsiStrScan。 – 2013-02-22 03:31:06
好評。多謝你們。我的實際代碼初始化'offset' - 我在這裏忽略了它。我會看看AnsiPosEx和AnsiStrScan。謝謝! – 2013-02-22 06:05:27