以前に受け入れられた回答からコードを取得し、2 つの変数を追加してわずかに変更しました。
FPosInt: NativeUInt;
FSize: NativeUInt;
FSize
コンストラクターで文字列の長さで初期化されます (文字列変数には長さが格納されていますが、PChar には格納されていません)。
FPosInt
ファイル内の現在の文字の番号です。コンストラクターの追加コード:
FSize := Length(FData);
FPosInt := 0;
関数の関連部分はGetNextToken
、最初の 0 バイトで停止するのではなく、文字列の最後の文字に到達するまで続きます。
// skip whitespace; this test could be converted to an unsigned int
// subtraction and compare for only a single branch
while (cp^ <= #32) and (FPosInt < FSize) do
begin
Inc(cp);
Inc(FPosInt);
end;
// end of file is reached if the position counter has reached the filesize
Result := FPosInt < FSize;
while 条件で 2 つのステートメントを切り替えました。これらは左から右に評価され、最初のステートメントはより頻繁に false と評価されるステートメントです。
別のアプローチでは、文字数をカウントしませんが、ポインターの開始位置を保存します。コンストラクターで:
FSize := Length(FData);
FStartPos := NativeUInt(FCurrPos);
そしてでGetNextToken
:
// skip whitespace; this test could be converted to an unsigned int
// subtraction and compare for only a single branch
while (cp^ <= #32) and ((NativeUInt(cp) - FStartPos) < FSize) do
Inc(cp);
// end of file is reached if the position counter has reached the filesize
Result := (NativeUInt(cp) - FStartPos) < FSize;