delphi - 索引列表越界(0) Delphi

标签 delphi

我有一段用delphi编写的代码,当我在客户端计算机上打开exe文件时,它说 索引列表超出范围(0),我搜索了整个谷歌,但无法修复,我必须如何修复它?有一些错误:D 感谢大家

代码:

    unit UntMain;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, StdCtrls, Forms,
  Graphics, ExtCtrls, Mask, Dialogs, Spin;

type
  TfrmMain = class(TForm)
    Panel1: TPanel;
    PaintBox1: TPaintBox;
    Button1: TButton;
    Timer1: TTimer;
    Edit1: TEdit;
    SpinEdit1: TSpinEdit;
    Button2: TButton;
    procedure PaintBox1Paint(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
    procedure Timer1Timer(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
    Head: Boolean;
    Body: Boolean;
    RArm: Boolean;
    LArm: Boolean;
    LLeg: Boolean;
    RLeg: Boolean;
    WordStr:String;
    SlashedWord: string;
    Loaded: Boolean;
  protected
   Dictionary: TStringList;
   procedure reset;
   procedure HangMan;
   function SolveWord(SlashedWord, WordStr: String; C: Char): String;
   function isHanged: Boolean;
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

uses UntHangman, UntAbout;

{$R *.dfm}

function TfrmMain.isHanged: Boolean;
begin
result:= (Head=True) AND (Body=True) AND (RARM=True) AND (LARM=true) AND (RLeg=True) AND (LLeg=true);
end;

procedure TfrmMain.HangMan;
begin
 if not Head then begin Head:= true; PaintBox1.Invalidate; exit; end else
 if not Body then begin Body:= true; PaintBox1.Invalidate; exit; end else
 if not RArm then begin RArm:= true; PaintBox1.Invalidate; exit; end else
 if not LArm then begin LArm:= true; PaintBox1.Invalidate; exit; end else
 if not RLeg then begin RLeg:= true; PaintBox1.Invalidate; exit; end else
 if not LLeg then begin LLeg:= true; PaintBox1.Invalidate; exit; end;
end;

function TfrmMain.SolveWord(SlashedWord, WordStr: String; C: Char): String;
var
 idx: Integer;
begin
 result:= SlashedWord;
 for Idx := 1 to length(WordStr) do
 begin
  if upcase(WordStr[Idx]) = upcase(C) then
  begin
   result[Idx]:= C;
  end;
 end;
end;


procedure TfrmMain.Timer1Timer(Sender: TObject);
var
 I: Integer;
begin
I:= SpinEdit1.Value;
if I <> 0 then
 begin

 I:= I-1;

 SpinEdit1.Value:=   SpinEdit1.Value -1;
 end
 else
begin
 Timer1.Enabled:= False;
 ShowMessage('You Lost!');
 reset;
 end;
end;

function SlashWord(Str: String): String;
var
 I: Integer;
begin
 for I := 1 to length(str) do
  if Str[I] <> ' ' then
   result:= result + '-'
  else
   result:= result + ' ';
end;

procedure TfrmMain.reset;
begin

 Head:= False;
 Body:= False;
 LArm:= False;
 RArm:= False;
 LLeg:= False;
 RLeg:= False;
 paintBox1.Invalidate;

 Edit1.Clear;
 SpinEdit1.Value:= 30;
end;

procedure TfrmMain.Button1Click(Sender: TObject);
var
 idx: Integer;
begin
idx:= random(Dictionary.Count);

 WordStr:= Dictionary[Idx];
 SlashedWord:= SlashWord(WordStr);
 Edit1.Text:= SlashedWord;
 Loaded:= True;

 Timer1.Enabled:= True;
end;

procedure TfrmMain.Button2Click(Sender: TObject);
begin
 frmAbout.ShowModal;
 PaintBox1.Invalidate;
end;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
 self.KeyPreview:= True;
 randomize;
 Dictionary:= TStringList.Create;

 if FileExists('Dictionary.dat') then
 Dictionary.LoadFromFile('Dictionary.dat');
end;

procedure TfrmMain.FormDestroy(Sender: TObject);
begin
Dictionary.Free;
end;

procedure TfrmMain.FormKeyPress(Sender: TObject; var Key: Char);
begin
if loaded then
 begin

 if pos(upcase(Key), Uppercase(WordStr)) > 0 then
 begin
 SlashedWord:= SolveWord(SlashedWord, WordStr, Key);
 Edit1.Text:= SlashedWord;
if Uppercase(SlashedWord) = UpperCase(WordStr) then
  begin
 Timer1.Enabled:= False;
 ShowMessage('You Won!');
 reset;

    exit;
  end;
 end
 else
 begin

  HangMan;
 if isHanged then
  begin

   Timer1.Enabled:= False;

   Edit1.Text:= WordStr;
   ShowMessage('You Lost!');

   reset;
   exit;
  end;
 end;
 end;
end;

procedure TfrmMain.PaintBox1Paint(Sender: TObject);
var
 X,Y: Integer;
begin
 inherited;
 with PaintBox1 do
 begin
 Canvas.Pen.Color:= clBlack;
 Canvas.Pen.Width:= 5;
 Canvas.Pen.Style:= psSolid;
 Canvas.Rectangle(1,1, ClientWidth-1, ClientHeight-1);
 Canvas.Brush.Color:= clWhite;
 Canvas.FloodFill(10,10,clBlack, fsBorder);
 Canvas.MoveTo(ClientWidth div 2, 1);
 Canvas.LineTo(Clientwidth div 2, ClientHeight Div 4);
 X:= Clientwidth div 2; Y:= ClientHeight Div 4;
 Canvas.Pen.Width:= 3;
 if Head then

 Canvas.Ellipse(X-25, Y-25, X+25, Y+25);
 Y:= Y + 25;
 Canvas.MoveTo(X, Y);
 if Body then
 Canvas.LineTo(X, Y + 100);
 Canvas.MoveTo(X, Y + 25);
 if LArm then
 Canvas.LineTo(X-25, Y+50);

 Canvas.MoveTo(X, Y + 25);

 if RArm then
 Canvas.LineTo(X+25, Y+50);

 Canvas.MoveTo(X, Y + 100);
 if LLeg then
 Canvas.LineTo(X-25, Y+150);

 Canvas.MoveTo(X, Y + 100);
 if RLeg then
 Canvas.LineTo(X+25, Y+150);
 end;
end;

end.

最佳答案

List of index out of bound(0)

这意味着您尝试引用列表的索引 0,但索引 0 处没有元素。换句话说,您的列表为空。

我可以看到代码中唯一可能导致该错误的地方是您从 Dictionary 读取项目的位置。因此,我得出的结论是 Dictionary 是空的。您从中加载的文件不存在,或者该文件为空。

此时代码

if FileExists('Dictionary.dat') then
  Dictionary.LoadFromFile('Dictionary.dat');

您需要做的不仅仅是默默地忽略丢失的文件。就我个人而言,我会删除对 FileExists 的检查,并尝试加载该文件,无论如何。如果加载失败,您的应用程序将引发异常。您还应该添加一个检查以确保字典不为空。

您的程序假定进程的工作目录与包含可执行文件的目录相同。情况可能并非总是如此。指定字典文件的完整路径,而不是使用相对路径(这对于 GUI 程序来说始终是一件脆弱的事情):

Dictionary.LoadFromFile(ExtractFilePath(Application.ExeName)+'Dictionary.dat');

您有多个 bool 值:

Head: Boolean;
Body: Boolean;
RArm: Boolean;
LArm: Boolean;
LLeg: Boolean;
RLeg: Boolean;

这些都应该替换为枚举类型:

type
  TState = (stHealthy, stHead, stBody, ..., stDead);

或者类似的东西。声明一个字段 FState: TState 并初始化为 stHealthy。每次用户猜错时,就写inc(FState)。当你到达stDead时,你就明白了。关键是状态有一个总顺序,所有这些 bool 值为您提供了比可能拥有的更大的灵 active 。它还会导致冗长且笨拙的代码。

关于delphi - 索引列表越界(0) Delphi,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16575018/

相关文章:

delphi - 命名空间和单位

delphi - TInterfacedObject 自动内存管理也可以与 C++Builder 一起使用吗?

forms - Delphi - Indy关闭所有与客户相关的表单

delphi - 如何申请 TLinkLabel 的 VCLStyle

delphi - 如何将我的应用程序静音?

delphi - Delphi中如何创建文件夹和txt文件

json - 使用 SuperObject 从 JSON 文件中提取值

Delphi ADOConnection 连接超时属性不起作用

Delphi计算WGS84 2点的交集

delphi - 如何更改默认的delphi停靠窗体标题高度?