Я использую следующий подход для перемещения и управления AnsiString
. Он работает большую часть времени, но иногда указатель на строку перестает функционировать. Учитывая следующий код:Delphi AnsiString Manipulation - 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>'
в инспекторе. Это так, как ожидалось.
Моя настоящая строка длиной несколько тысяч символов. Этот метод перемещения по строке и добавление новых полей работает десятки раз, а затем внезапно перестает работать. p
больше не показывает вставленное значение в начале строки после вызова Insert()
. p
, кажется, не знают, что s
изменилось ...
Почему p
правильно ссылаться на символ на s
после самой Insert()
заявления, и вдруг перестают работать после нескольких звонков в Insert()
?
(Я обнаружил ответ на свой вопрос, набрав его. Ответ кажется очевидным сейчас, но не так, пока я боролся с проблемой. Возможно, вопрос и ответ помогут кому-то другому ...)
Just FYI: В вашем вопросе и вашем ответе вы никогда не инициализируете 'offset', прежде чем использовать его в цикле. Поэтому вы начинаете со случайного содержимого памяти и каждый раз увеличиваете его с помощью значения idx каждый через цикл. –
То, что вы действительно можете использовать здесь, если оно существует, это «AnsiPosEx», функция, которая объединяет MBCS-осведомленность AnsiPos с настраиваемым индексом начала PosEx. Тогда вам вообще не понадобится 'p', и это спасет вас от создания и уничтожения строк длиной в несколько тысяч символов каждый раз, когда вы передаете' p' в качестве параметра, который ожидает, что AnsiString и компилятор выполнит автоматическое преобразование для вы. Если ваш поисковый запрос действительно один символ, тогда рассмотрите вместо этого использование AnsiStrScan. –
Хорошие комментарии. Спасибо, парни. Мой фактический код инициализирует 'offset' - я просто упустил его здесь. Я также посмотрю AnsiPosEx и AnsiStrScan. Благодаря! –