How to read a specific line from a text file ?
Except the LoadStringsFromFile
function there's not much you can use from that function. The next function I wrote loads a text file given by the FileName
parameter, and tries to copy the line from the 0 based index Index
to the output parameter Line
. If loading of the given file succeed and the file has enough lines to satisfy the requested Index
, it returns True, False otherwise.
function TryGetFileLine(const FileName: string; Index: Integer; out Line: string): Boolean;
var
FileLines: TArrayOfString;
begin
// the function succeed when the file can be loaded and the count of lines is
// greater than the requested line index (it is 0 based index, hence the line
// count must be greater)
Result := LoadStringsFromFile(FileName, FileLines) and (GetArrayLength(FileLines) > Index);
// if the above succeeded, return the file line of the requested index to the
// output parameter
if Result then
Line := FileLines[Index];
end;
For shorter code I chose 0 based indexing, so if you would like to read the first line of the file, you would request the index 0, second line index 1 and so forth. To get the first line it would be:
var
S: string;
begin
// if the file could be opened and has at least one line, then the following
// call succeed and the variable S will contain the first line of the file
if TryGetFileLine('C:\File.txt', 0, S) then
MsgBox('The first line of the given file is: ' + S, mbInformation, MB_OK);
end;
How to convert string to integer ?
There are at least two ways to convert string to 32-bit integer in Inno Setup at this time. The StrToInt
function and StrToIntDef
. The first one tries to convert the passed string to integer and if that fails, it returns -1. The second does the same except if the conversion fails, it returns the value specified by the def
parameter.
Unfortunately, none of the above functions can reliably tell if the given string has been converted without losing one value in the integer range. Consider the following code:
var
Value1: Integer;
Value2: Integer;
begin
Value1 := StrToInt('-1');
Value2 := StrToInt('Non integer');
if Value1 = Value2 then
begin
MsgBox('Err, the result is the same for string of value -1 and for a non ' +
'integer string.', mbInformation, MB_OK);
end;
end;
The above code demostrates, that if you'll use the StrToInt
function, you won't be able to determine whether the string (in your case a line read from file) contains the value -1
or a non integer value. The similar applies to the def
parameter of the StrToIntDef
function.
However, you can sanitize this problem if you explicitly check if the string contains value that the function returns in case when the conversion fails. The following function returns True if the string S
contains a valid integer value, False otherwise. If the conversion succeeds, the converted value is returned to the output Value
parameter:
function TryStrToInt(const S: string; out Value: Integer): Boolean;
var
I: Integer;
begin
I := StrToIntDef(S, -1);
Result := (I <> -1) or (S = '-1');
if Result then
Value := I;
end;
Usage of this function looks like this:
var
I: Integer;
begin
if TryStrToInt('12345', I) then
begin
MsgBox('The passed string was converted to integer. Its value is: ' +
IntToStr(I), mbInformation, MB_OK);
end;
end;
Safely to the end...
You didn't mention what are the version values in your text file, so I've assumed they are 32-bit integers and might have any value in the range (even though I believe in real you'll be using only positive values where the built-in string to integer conversion functions might suffice).
Still, having a safer string to integer conversion function in the codebase is fine. So let's stick the above functions together to attempt to read the first line of a text file and convert it to integer:
var
S: string;
I: Integer;
begin
// if the first line of the file was successfully read and could have been
// converted to integer, then...
if TryGetFileLine('C:\File.txt', 0, S) and TryStrToInt(S, I) then
begin
MsgBox('The first line of the given file was successfully read and could ' +
'have been converted to integer. Its value is: ' + IntToStr(I),
mbInformation, MB_OK);
// here the variable I contains the value that you can compare in a way
// of your choice
end;
end;