【发布时间】:2013-02-07 13:13:45
【问题描述】:
我使用以下方法来移动和操作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>'。这符合预期。
我的真实字符串有几千个字符长。这种在字符串中移动并添加新字段的方法工作了几十次,然后突然停止工作。在调用Insert() 之后,p 不再在字符串前面显示插入的值。 p 好像不知道s 变了……
为什么p 在大多数Insert() 语句之后正确引用s 上的一个字符,并在对Insert() 进行一些调用后突然停止工作?
(我在打字时发现了我的问题的答案。现在答案似乎很明显,但在我为这个问题而苦苦挣扎时并非如此。也许发布问题和答案会对其他人有所帮助...... )
【问题讨论】:
-
仅供参考:在您的问题和答案中,您永远不会在循环中使用
offset之前对其进行初始化。因此,您从随机内存内容开始,并在每次循环中以idx的值递增它。 -
如果存在的话,您真正可以在这里使用的是“AnsiPosEx”,该函数将 AnsiPos 的 MBCS 感知与 PosEx 的可配置起始索引相结合。那么您根本不需要
p,这样每次您将p作为需要AnsiString 的参数传递并且编译器会自动转换为你。如果您的搜索词确实是一个字符,请考虑改用 AnsiStrScan。 -
好的cmets。多谢你们。我的实际代码初始化
offset- 我只是在这里忽略了它。我也会看看 AnsiPosEx 和 AnsiStrScan。谢谢!
标签: delphi pointers delphi-xe2 ansistring