From: Foundry
I am making a script for a game that writes to an event log around every 15 seconds. How would I get a string of the last line of the .txt file? I looked at the documentation for Simba regarding file i/o but I am a little confused. Could someone guide me in the right direction?
Hello Foundry,
Here is some string handling commands, that I wrote for pumbaa plugin, which you could possibly use for file reading tasks:
{==============================================================================]
Explodes str with multiple separators/delimiters (d).
The importance order for d items is from left to right (=>).
So place the important ones first and then less important after those.
[==============================================================================}
function StrExplodeMulti(d: TStringArray; str: string): TStringArray;
var
a, b, i, l, p, r, s, z, g: Integer;
m: Boolean;
begin;
SetLength(Result, 1);
l := Length(str);
s := Length(d);
if ((l > 0) and (s > 0)) then
begin
r := 0;
z := 0;
for a := 0 to (s - 1) do
begin
p := Length(d[a]);
if (p > 0) then
if (p <= l) then
begin
if (z = 0) then
z := Length(d[a])
else
if (Length(d[a]) < z) then
z := Length(d[a]);
d[r] := d[a];
Inc(r);
end;
end;
if (r > 0) then
begin
s := r;
a := 1;
p := 1;
r := 0;
while ((a + (z - 1)) <= l) do
begin
m := False;
for i := 0 to (s - 1) do
begin
g := Length(d[i]);
if ((a + (g - 1)) <= l) then
begin
for b := 1 to g do
begin
m := (str[((a + b) - 1)] = d[i][b]);
if not m then
Break;
end;
if m then
Break;
end;
end;
if m then
begin
Result[r] := Copy(str, p, (a - p));
if ((a + (g + 1)) = l) then
Exit;
p := (a + g);
a := ((a + g) - 1);
Inc(r);
SetLength(Result, (r + 1));
end;
Inc(a);
end;
Result[r] := Copy(str, p, ((l - p) + 1));
end else
Result[0] := '';
end else
Result[0] := '';
end;
{==============================================================================]
Explodes str with multiple separators/delimiters (d).
The importance order for d items is from left to right (=>).
So place the important ones first and then less important after those.
NOTE: Supports limit.
[==============================================================================}
function StrExplodeMultiEx(d: TStringArray; str: string; limit: Integer): TStringArray;
var
a, b, i, l, p, r, s, z, g: Integer;
m: Boolean;
begin;
SetLength(Result, 1);
l := Length(str);
s := Length(d);
if ((l > 0) and (s > 0)) then
begin
r := 0;
z := 0;
for a := 0 to (s - 1) do
begin
p := Length(d[a]);
if (p > 0) then
if (p <= l) then
begin
if (z = 0) then
z := Length(d[a])
else
if (Length(d[a]) < z) then
z := Length(d[a]);
d[r] := d[a];
Inc(r);
end;
end;
if (r > 0) then
begin
s := r;
a := 1;
p := 1;
r := 0;
while (((r + 1) < limit) and ((a + (z - 1)) <= l)) do
begin
m := False;
for i := 0 to (s - 1) do
begin
g := Length(d[i]);
if ((a + (g - 1)) <= l) then
begin
for b := 1 to g do
begin
m := (str[((a + b) - 1)] = d[i][b]);
if not m then
Break;
end;
if m then
Break;
end;
end;
if m then
begin
Result[r] := Copy(str, p, (a - p));
if ((a + (g + 1)) = l) then
Exit;
p := (a + g);
a := ((a + g) - 1);
Inc(r);
SetLength(Result, (r + 1));
end;
Inc(a);
end;
Result[r] := Copy(str, p, ((l - p) + 1));
end else
Result[0] := '';
end else
Result[0] := '';
end;
{==============================================================================]
Returns the lines of str as TStringArray.
[==============================================================================}
function StrLines(str: string): TStringArray;
var
d: TStringArray;
begin
if (str <> '') then
begin
SetLength(d, 3);
d[0] := #13#10;
d[1] := #13;
d[2] := #10;
Result := StrExplodeMulti(d, str);
end else
begin
SetLength(Result, 1);
Result[0] := str;
end;
end;
{==============================================================================]
Returns the total count of lines that str contains.
[==============================================================================}
function StrLineCount(str: string): Integer;
var
s: TStringArray;
begin
if (str <> '') then
begin
s := StrLines(str);
Result := Length(s);
end else
Result := 1;
end;
{==============================================================================]
Returns the line text from str by number.
NOTE: Line numbers start from 1!
[==============================================================================}
function StrLine(str: string; number: Integer): string;
var
d, r: TStringArray;
begin
if ((str <> '') and (number > 0)) then
begin
SetLength(d, 3);
d[0] := #13#10;
d[1] := #13;
d[2] := #10;
r := StrExplodeMultiEx(d, str, (number + 1));
if (Length(r) >= number) then
Result := r[(number - 1)]
else
Result := '';
end else
Result := '';
end;
var
f, h, i: Integer;
p, s: string;
d: TStringArray;
r: Boolean;
begin
p := (AppPath + 'settings.xml');
f := OpenFile(p, False);
r := ReadFileString(f, s, FileSize(f));
CloseFile(f);
if r then
begin
ClearDebug;
d := StrLines(s);
h := High(d);
for i := 0 to h do
WriteLn('Line ' + IntToStr(i + 1) + ' = "' + d[i] + '"');
SetLength(d, 0);
i := StrLineCount(s);
WriteLn('Count of lines in file: ' + IntToStr(i));
if (i > 0) then
WriteLn('Last line (' + IntToStr(i) + '): "' + StrLine(s, i) + '"');
end;
end.
Provided a small example how you can use em. :) You need to change the p variable to your own path, of course.
Hope any of it helps you out!
P.S. StrExplodeMulti and StrExplodeMultiEx are core functions, that those string line reading functions (StrLines, StrLine, StrLineCount) are based on. :)
Edit: I accidentally said File commands, even though they are String commands that could be used with file strings - it's correct now!