如何修复 Pascal 中的外部:访问冲突错误?

发布于 2025-01-10 20:36:49 字数 3452 浏览 1 评论 0原文

我在 Pascal 中遇到错误,根据我的研究,这是由于声明错误(类或变量)造成的。它一定是小东西,因为它运行得很好。我真的很感激任何帮助。

更具体地说,我收到的错误是:

“外部:访问违规”,包含消息:从地址 $000004A8 读取的读取违规。第 66 行:Efa.Text:=D.Fa ;

unit UnidadProyectoInformaticaUno;

{$mode objfpc}{$H+}{$R+}{$Q+}

interface

uses
   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,Math;

type

{ TForm1 }

TForm1 = class(TForm)
   BNext: TButton;
   BPrev: TButton;
   BAdd: TButton;
   BDel: TButton;
   BClose: TButton;
   EFa: TEdit;
   EIm: TEdit;
   EOch: TEdit;
   EOt: TEdit;
   ENum: TEdit;
   LabFa: TLabel;
   LabIm: TLabel;
   LabOch: TLabel;
   LabOt: TLabel;
   LabNUM: TLabel;

   procedure BAddClick(Sender: TObject);
   procedure BCloseClick(Sender: TObject);
   procedure BDelClick(Sender: TObject);
   procedure BNextClick(Sender: TObject);
   procedure BPrevClick(Sender: TObject);


   private

   public

   end;

   var
      Form1: TForm1;

   implementation

   {$R *.lfm}
   type
      R= record
         Fa,Im,Och: string[20];
         Ot:array[1..5] of integer;
      end;
   Var F:file of R;
      D,D1,D2:R;
      Irec,i,j,k:integer;
      note,grade,nada:string;

   procedure OutRec;
   begin
      with Form1 do
      IF Irec > 0 then
      begin
           seek(F,Irec-1);
           read(F,D);
           EFa.Text:=D.Fa;
           EIm.Text:=D.Im;

           for i:= 1 to 5 do
              begin
                 grade:= grade +IntToStr(D.Ot[i])+' ';
              end;

           Eot.Text:=grade;
           EOch.Text:=D.Och;
           Enum.Text:= IntToStr(Irec);

      end
      else
      begin
         EFa.Text:=nada;
         Enum.Text:=nada;
      end;
   end;

   { TForm1 }

   procedure TForm1.BNextClick(Sender: TObject);
   begin
      If Irec = filesize(F) then
      Exit
      else
      Irec:= Irec+1;
      OutRec;
   end;

   procedure TForm1.BAddClick(Sender: TObject);
   begin
      D.Fa:=Efa.Text;
      D.Im:=Eim.Text;
      D.Och:=EOch.Text;
      Note:= Eot.text;
   for i:= 1 to 5 do
       begin
          k:=Pos(' ',Note);
          D.Ot[i]:= strToInt(Copy(Note,1,k-1));
          Delete(Note,1,k);
       end;

   seek(F,FileSize(F));
   Write(F,D);
   Irec:= FileSize(F);
   OutRec;
 end;

 procedure TForm1.BCloseClick(Sender: TObject);
 begin
     close
 end;

 procedure TForm1.BDelClick(Sender: TObject);
 begin
 for i:= Irec+1 to Filesize(F) do
    begin
    seek(F,i-1);
    read(F,D);
    Seek(F,i-2);
    Write(F,D);
end;

Seek(F,Filesize(f)-1);
   Truncate(F);
   Irec:= Min(Irec,FileSIze(F));
   Outrec;
end;

procedure TForm1.BPrevClick(Sender: TObject);
   begin
   if Irec<2 then Exit;
   Irec:= Irec-1;
   OutRec;
end;

function Sort(Z:R):string;
begin
     Result:=Z.Fa+' '+Z.Im+' '+Z.Och;
end;

procedure  BStatus;
    begin
    with Form1 do
    BNext.Enabled:= Irec < FileSize(f);
end;

procedure  B1Status;
    begin
    with Form1 do
    BPrev.Enabled:= Irec > 1;
end;

procedure  B2Status;
    begin
    with Form1 do
    BAdd.Enabled:= length(Eot.Text) > 0 ;
end;

procedure  B3Status;
    begin
    with Form1 do
    BDel.Enabled:= IRec > 0;
end;

begin

assignfile(F,'file.dat');
    try reset(F);
    except
    rewrite(F);
end;

Irec:= Min(1,filesize(F));
OutRec;


for i :=1 to filesize(F)-1 do
  for j:= Filesize(F) to i  do
  begin
     seek(F,i);
     read(F,D1,D2);
     if Sort(D1)>Sort(D2) then
  begin

  write(f,D2,D1);
  end;

  end;
end.

I'm getting an error in Pascal, and according to my research it's due to a declaration error (class or variable). It has to be something small, since it was working just fine. I would really appreciate any help.

To be more specific, the error I'm getting is:

'External:ACCESS VIOLATION' with message: Accedd violation reading from address $000004A8. In line 66: Efa.Text:=D.Fa ;

unit UnidadProyectoInformaticaUno;

{$mode objfpc}{$H+}{$R+}{$Q+}

interface

uses
   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,Math;

type

{ TForm1 }

TForm1 = class(TForm)
   BNext: TButton;
   BPrev: TButton;
   BAdd: TButton;
   BDel: TButton;
   BClose: TButton;
   EFa: TEdit;
   EIm: TEdit;
   EOch: TEdit;
   EOt: TEdit;
   ENum: TEdit;
   LabFa: TLabel;
   LabIm: TLabel;
   LabOch: TLabel;
   LabOt: TLabel;
   LabNUM: TLabel;

   procedure BAddClick(Sender: TObject);
   procedure BCloseClick(Sender: TObject);
   procedure BDelClick(Sender: TObject);
   procedure BNextClick(Sender: TObject);
   procedure BPrevClick(Sender: TObject);


   private

   public

   end;

   var
      Form1: TForm1;

   implementation

   {$R *.lfm}
   type
      R= record
         Fa,Im,Och: string[20];
         Ot:array[1..5] of integer;
      end;
   Var F:file of R;
      D,D1,D2:R;
      Irec,i,j,k:integer;
      note,grade,nada:string;

   procedure OutRec;
   begin
      with Form1 do
      IF Irec > 0 then
      begin
           seek(F,Irec-1);
           read(F,D);
           EFa.Text:=D.Fa;
           EIm.Text:=D.Im;

           for i:= 1 to 5 do
              begin
                 grade:= grade +IntToStr(D.Ot[i])+' ';
              end;

           Eot.Text:=grade;
           EOch.Text:=D.Och;
           Enum.Text:= IntToStr(Irec);

      end
      else
      begin
         EFa.Text:=nada;
         Enum.Text:=nada;
      end;
   end;

   { TForm1 }

   procedure TForm1.BNextClick(Sender: TObject);
   begin
      If Irec = filesize(F) then
      Exit
      else
      Irec:= Irec+1;
      OutRec;
   end;

   procedure TForm1.BAddClick(Sender: TObject);
   begin
      D.Fa:=Efa.Text;
      D.Im:=Eim.Text;
      D.Och:=EOch.Text;
      Note:= Eot.text;
   for i:= 1 to 5 do
       begin
          k:=Pos(' ',Note);
          D.Ot[i]:= strToInt(Copy(Note,1,k-1));
          Delete(Note,1,k);
       end;

   seek(F,FileSize(F));
   Write(F,D);
   Irec:= FileSize(F);
   OutRec;
 end;

 procedure TForm1.BCloseClick(Sender: TObject);
 begin
     close
 end;

 procedure TForm1.BDelClick(Sender: TObject);
 begin
 for i:= Irec+1 to Filesize(F) do
    begin
    seek(F,i-1);
    read(F,D);
    Seek(F,i-2);
    Write(F,D);
end;

Seek(F,Filesize(f)-1);
   Truncate(F);
   Irec:= Min(Irec,FileSIze(F));
   Outrec;
end;

procedure TForm1.BPrevClick(Sender: TObject);
   begin
   if Irec<2 then Exit;
   Irec:= Irec-1;
   OutRec;
end;

function Sort(Z:R):string;
begin
     Result:=Z.Fa+' '+Z.Im+' '+Z.Och;
end;

procedure  BStatus;
    begin
    with Form1 do
    BNext.Enabled:= Irec < FileSize(f);
end;

procedure  B1Status;
    begin
    with Form1 do
    BPrev.Enabled:= Irec > 1;
end;

procedure  B2Status;
    begin
    with Form1 do
    BAdd.Enabled:= length(Eot.Text) > 0 ;
end;

procedure  B3Status;
    begin
    with Form1 do
    BDel.Enabled:= IRec > 0;
end;

begin

assignfile(F,'file.dat');
    try reset(F);
    except
    rewrite(F);
end;

Irec:= Min(1,filesize(F));
OutRec;


for i :=1 to filesize(F)-1 do
  for j:= Filesize(F) to i  do
  begin
     seek(F,i);
     read(F,D1,D2);
     if Sort(D1)>Sort(D2) then
  begin

  write(f,D2,D1);
  end;

  end;
end.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绻影浮沉 2025-01-17 20:36:49

在 Free Pascal 参考指南 3.04 版(2018 年 5 月)第 16.2 段中,涉及 Units ,据说一个单元可能有一个 initialization 部分和一个 完成 部分。还有人说:“初始化部分本身(即没有终结)可以简单地用语句块替换。”,这就是您代码中的内容。

该语句块位于单元的 beginend 之间,在创建 Form1(在同一单元中声明)之前在程序初始化时执行。因此,您不能在此语句块中直接或间接引用属于表单的任何内容,例如字段、控件、方法等。

您正在调用procedure OutRec,它引用表单的Efa: TEdit。由于表单尚未创建,您会收到访问冲突错误。

您必须重新排列代码,以便它不会尝试从替换单元初始化部分的语句块访问表单的任何部分。

In Free Pascal Reference guide, version 3.04 (May 2018), Paragraph 16.2 that deals with Units, it is said that a unit may have an initialization part and a finalization part. It is also said: "An initialization section by itself (i.e. without finalization) may simply be replaced by a statement block.", which is what you have in your code.

That statement block, between the begin and end of the unit, executes at program initialization before the Form1 (declared in the same unit) is created. Therefore you can not refer to anything belonging to the form, like fields, controls, methods, etc. in this statement block, neither directly nor indirectly.

You are calling procedure OutRec, which refers to Efa: TEdit of the form. Since the form is not yet created, you get the error of Access violation.

You must rearrange your code so it doesn't attempt to access any parts of the form from the statement block that replaces a unit initialization part.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文