Я использую следующий подход для перемещения и управления файлом AnsiString
. В большинстве случаев это работает, но иногда указатель на строку перестает работать. Учитывая следующий код:
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()
?
(Я нашел ответ на свой вопрос, когда набирал его. Ответ кажется очевидным сейчас, но не так, пока я боролся с проблемой. Возможно, публикация вопроса и ответа поможет кому-то еще...) эм>
offset
, прежде чем использовать его в цикле. Таким образом, вы начинаете со случайного содержимого памяти и увеличиваете его на значениеidx
каждый раз в цикле. - person Ken White   schedule 22.02.2013p
, и это избавит вас от создания и уничтожения строк длиной в несколько тысяч символов каждый раз, когда вы передаетеp
в качестве параметра, который ожидает AnsiString, а компилятор выполняет автоматическое преобразование за вас. Если ваш поисковый запрос действительно состоит из одного символа, рассмотрите возможность использования вместо него AnsiStrScan. - person Rob Kennedy   schedule 22.02.2013offset
- я просто пропустил это здесь. Присмотрюсь еще к AnsiPosEx и AnsiStrScan. Спасибо! - person James L.   schedule 22.02.2013