how to find my error(delphi)

354 views Asked by At

i'm getting an I/o 998 error, my task is to rewrite numbers from file to array, and find max and min values. What i'm doing wrong ?

implementation

var
  f2: file of Real;
  m: array of Real;

procedure TForm1.Button1Click(Sender: TObject);
var 
  f: Real;
  max, min: Real;
  i, j: Integer;
begin
  AssignFile(F2, 'test3.dat');
  Rewrite(f2);

  for i := 1 to 50 do
  begin
    f := RandomRange(-100, 100);
    Randomize;
    Write(f2, f);
  end;

  CloseFile(f2);

  i := 0;

  Reset(f2);

  while not Eof(f2) do
  begin
    SetLength(m, i);
    Read(f2, m[i]);
    Inc(i);
  end;

  CloseFile(f2);

  max := m[1];
  min := m[1];

  for j := 1 to i do
    if m[j] > max then
      max := m[j]
    else 
    if m[j] < min then
      min := m[i];
2

There are 2 answers

5
Sertac Akyuz On
  i := 0;

  Reset(f2);

  while not Eof(f2) do
  begin
    SetLength(m, i);
    Read(f2, m[i]);
    Inc(i);
  end;

The above code sets the length of a dynamic array to 0 (i) and tries to read into its non-existing element. This causes the RTL to pass an invalid buffer to ReadFile api. The OS returns '0' indicating the function failed and sets the last error to '998' - that's ERROR_NOACCESS. RTL sets the in/out error code and raises it.

As for the answer, use the debugger. Break when the debugger raises an exception. On the next run, put a breakpoint on the faulting statement then trace into code (RTL in this case). Additionally, should you have 'range checking' on in compiler options, you'd get a range check error instead of an I/O error, in which case you would probably see the mistake quickly.

9
LU RD On

Many errors, see comments in code.

  • Randomize should be called once at program start.
  • Dynamic arrays has start index 0.
  • CloseFile releases file handle
  • Define length of the dynamic array before the loop, otherwise you will get i/O error.
  • High(m) will get the max index of the dynamic array.
  • Index variable for assigning the min value is j.

implementation

var
  f2: file of Real;
  m: array of Real;

procedure TForm1.Button1Click(Sender: TObject);
var 
  f: Real;
  max, min: Real;
  i, j: Integer;
begin
  AssignFile(F2, 'test3.dat');
  Rewrite(f2);

  for i := 1 to 50 do
  begin
    f := RandomRange(-100, 100);
    //Randomize;  <-- Call this once at program start
    Write(f2, f);
  end;

  //CloseFile(f2); <-- Don't close yet.

  Reset(f2);
  SetLength(m, 50);  // <-- Define length of dynamic array
  i := 0;
  while not Eof(f2) do
  begin
    // SetLength(m, i); // <-- Moved to before while loop, or use SetLength(m,i+1);
    Read(f2, m[i]);
    Inc(i);
  end;

  CloseFile(f2);

  max := m[0];  // <-- Dynamic arrays start with index 0
  min := m[0];  // <-- Dynamic arrays start with index 0

  for j := 1 to High(m) do // <- Max index
    if m[j] > max then
      max := m[j]
    else 
    if m[j] < min then
      min := m[j]; // <-- j is correct index variable