A very good comment, thanks for pointing this out.
With your connivance
I'll add another comment.
The code to extract the word (Pos+Copy+Delete) must be in a separate function. Apart from obvious advantages such as improved readability and size reduction, it is more deterministic.
Illustrate. The example above does not specify what is done with read variables. Let them is transmitted to some procedure DoWork.
As a result, the code will be similar to this:
AssignFile(txtf, 'termek.txt');
Reset(txtf);
try
while not Eof(txtf) do
begin
// Your code
DoWork(productCity, productName, productCount);
end;
...
What happens if the input string contains incomplete data? Then the data from the previous iteration(s) will be transferred to the DoWork procedure. This is not a deterministic result.
Now extract the code to a separate function, for example:
function ExtractWord(var S: string): string;
var
SpacePos: Integer;
begin
SpacePos := Pos(' ', S);
if SpacePos = 0 then
SpacePos := Length(S) + 1;
Result := Copy(S, 1, SpacePos - 1);
Delete(S, 1, SpacePos);
end;
and do
productCity := ExtractWord(s);
productName := ExtractWord(s);
productCount := StrToIntDef(ExtractWord(s), -1); // Yes do ExtractWord to support future extended format of file
DoWork(productCity, productName, productCount);
In this case, if the input data is incomplete, we always pass null values.