Reputation: 12391
I hava a form, and on a button click I want to read a file. That is fine, my program does it.
temekek.txt
includes string string integer
.
Reading of the file is fine.
I want to do some validation, so I want to check how many cities
(first string) in the file.
My idea is to collect all unique cities in an array.
When I want to create a dynamic array, I've got an erreor SIGSEGV
.
I uninstalled mine 64bit Lazarus, and installed 32bit, the result is the same.
Here is my program:
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, strutils;
type
{ TmainForm }
TmainForm = class(TForm)
readProcutsBtn: TButton;
procedure readProcutsBtnClick(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
type
productFileRow = record
productCity, productName: string;
productCount: integer;
end;
var
mainForm: TmainForm;
productFileDataArray: array[1..200] of productFileRow;
isProductFileValid: boolean;
const
minCities = 2;
const
maxCities = 50;
const
productsFile = 'termek.txt';
implementation
{$R *.lfm}
{ TmainForm }
procedure readProducts;
var
i: integer;
productFileIn: TextFile;
line: string;
begin
assignFile(productFileIn, productsFile);
reset(productFileIn);
i := 0;
while not EOF(productFileIn) do
begin
readLn(productFileIn, line);
SScanf(Line, '%s %s %d', [@productFileDataArray[i].productCity,
@productFileDataArray[i].productName, @productFileDataArray[i].productCount]);
i := i + 1;
end;
closefile(productFileIn);
end;
function validateCityCount: boolean;
var
cities: array of string;
productFileRowItem: productFileRow;
i: integer;
begin
for productFileRowItem in productFileDataArray do
begin
i := 0;
if not (AnsiMatchStr(productFileRowItem.productCity, cities)) then
begin
SetLength(cities, i);
cities[i] := productFileRowItem.productCity;
i := i + 1;
end;
end;
validateCityCount := False;
end;
procedure TmainForm.readProcutsBtnClick(Sender: TObject);
begin
readProducts;
if not validateCityCount then
begin
ShowMessage('Sorry, product file is invalid, too much or too less cities');
Exit;
end;
ShowMessage('Products readed form `' + productsFile + '`');
end;
end.
My program dies at this row:
cities[i] := productFileRowItem.productCity;
Upvotes: 0
Views: 973
Reputation: 34899
You set SetLength(cities,i)
with a one off length. First time i
is zero, which means an empty array. Next line tries to access first element in the array, which causes the crash.
To correct:
SetLength(cities,i+1);
Upvotes: 3