【问题标题】:Loading an array of records back into a program from a file?将记录数组从文件加载回程序?
【发布时间】:2016-03-15 12:29:53
【问题描述】:

我正在创建一个程序,该程序在记录数组中移动并将这些学生记录保存到文件中。

但是我现在希望将数据(学生姓名、班级、年级)重新加载到数组中,然后将它们显示在另一个表单的列表框中。

我尝试了几种方法,但都没有成功。

这是编写文件的代码:

unit NewStudent;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls, studentdata;


  { TFormNewStudent }
Type
  TFormNewStudent = class(TForm)
    Button1: TButton;
    ButtonAddStudent: TButton;
    Button3: TButton;
    ComboBoxPredictedGrade: TComboBox;
    EditClass: TEdit;
    EditName: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure ButtonAddStudentClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);

  private
    { private declarations }
  public
    { public declarations }
  end;

Type
  TPupil = Record
    Name:String[30];
    ClassGroup:String;
    ComboBoxPredictedGrade:Integer;
  end;

var
  FormNewStudent: TFormNewStudent;
  StudentRecArray : Array[1..30] of TPupil;
  StudentNo:integer;
  studentFile:TextFile;
implementation

{$R *.lfm}

{ TFormNewStudent }

procedure TFormNewStudent.Button1Click(Sender: TObject);
begin
   FormStudentData.visible:=true;
  FormNewStudent.visible:=false;
end;

procedure TFormNewStudent.Button3Click(Sender: TObject);
begin
  FormStudentData.visible:=False;
  FormNewStudent.visible:=True;
end;

procedure TFormNewStudent.ButtonAddStudentClick(Sender: TObject);
var
   newStudent:string;
Begin
   assignfile(studentFile,'G:\ExamGen\studentfile.txt');
   StudentRecArray[StudentNo].Name:=EditName.text;
   StudentRecArray[StudentNo].ClassGroup:=EditClass.text;
   StudentRecArray[StudentNo].ComboBoxPredictedGrade:=ComboBoxPredictedGrade.ItemIndex;
   append(studentFile);
   newStudent:=(StudentRecArray[StudentNo].Name)+','+(StudentRecArray[StudentNo].ClassGroup)+','+(IntToStr(StudentRecArray[StudentNo].ComboBoxPredictedGrade));
   writeln(studentFile,newStudent);
   closefile(StudentFile);
   StudentNo := StudentNo + 1;
end;

procedure TFormNewStudent.FormCreate(Sender: TObject);
begin
  ComboBoxPredictedGrade.Items.Add('A');
  ComboBoxPredictedGrade.Items.Add('B');
  ComboBoxPredictedGrade.Items.Add('C');
  ComboBoxPredictedGrade.Items.Add('D');
  ComboBoxPredictedGrade.Items.Add('E');
  ComboBoxPredictedGrade.Items.Add('U');
end;



end.                    

屏幕截图 1:StudentFile
截图 2:AddStudent Form

【问题讨论】:

  • 请将学生文件中的内容添加为文本,而不是屏幕截图。它实际上并没有那么大,我们将无法从图像中复制/粘贴。
  • 您尝试过的几种方法是什么? “没有成功”是什么意思?有错误吗?结果与您的预期有何不同?如果您想要“最佳方法”,则可能是使用数据库来存储此信息。
  • 你的ClassGroup: string 永远不会工作,因为它没有定义的长度。您需要使用ShortString,就像使用Name: string[30]; 一样。话虽如此,一个没有明确问题陈述的问题(我尝试了几种方法都没有成功)是非常难以提出的,并且图像只能用于无法演示的事情作为文本。由于您的文件是文本,因此绝对没有理由将其放在图像中,并且您的表单图像完全没有意义和无关紧要。如果您希望我们提供帮助,请让我们尽可能轻松地提供帮助。
  • 你用的是什么版本的Delphi?

标签: lazarus freepascal


【解决方案1】:

Zamrony P. Juhara 给出的答案是正确的,但您在这里的方法可能不是最方便的。您定义包含有关每个学生的信息的记录,然后编写程序将此记录写入文件并读取另一个记录。如果您最终要更改记录的格式,则还必须重写此代码。在我看来,还有更好的方法。

您可以定义只包含最简单成员的记录,就像 Ken White 建议的那样:

  TPupil = Record
    Name:String[30];
    ClassGroup:String[20]; //some convenient value
    ComboBoxPredictedGrade:Integer;
  end;

这样的记录具有固定的大小,并且本身包含所有需要的信息(带有ClassGroup:String 的版本实际上存储了指向您的字符串所在内存中另一个区域的指针),然后您可以非常轻松地保存和加载它:

var
  myFile : File of TPupil;

procedure TFormNewStudent.ButtonAddStudentClick(Sender: TObject);
Begin
   assignfile(studentFile,'G:\ExamGen\studentfile.txt');
   StudentRecArray[StudentNo].Name:=EditName.text;
   StudentRecArray[StudentNo].ClassGroup:=EditClass.text;
   StudentRecArray[StudentNo].ComboBoxPredictedGrade:=ComboBoxPredictedGrade.ItemIndex;
   append(studentFile);

   Write(studentFile,StudentRecArray[StudentNo]); //THAT'S IT!

   closefile(StudentFile);
   inc(StudentNo);
end;

procedure TFormNewStudent.ReadFromFile;
begin
  AssignFile(myFile,'G:\ExamGen\studentfile.txt');
  Reset(studentFile);

  StudentNo:=1;
  while not Eof(studentFile) do begin
    Read(studentFile,StudentRecArray[i]);
    inc(StudentNo);
  end;
end;

有一点缺点:文件不像以前那么可读了,因为整数完全保存为 4 字节值,而不是十进制表示。

如果您从记录转移到类,则有更多有趣的可能性,在这种情况下,您可以使用流系统,因为 IDE 将表单保存到磁盘、.dfm 或 .lfm 文件中,因此您将能够自动保存对象的复杂层次结构并重新加载它们。

【讨论】:

    【解决方案2】:
    var
      myFile : TextFile;
      text   : string;
      lines  : TStringList;
      i      : integer;
    ...
    
    lines := TStringList.Create();
    AssignFile(studentFile,'G:\ExamGen\studentfile.txt');
    Reset(studentFile);
    
    i:=1;
    while not Eof(studentFile) do
    begin
      ReadLn(studentFile, text);
      lines.CommaText := text;
      studentRecArray[i].Name := lines[0];
      studentRecArray[i].ClassGroup := lines[1];
      studentRecArray[i].ComboBoxPredictedGrade := StrToInt(lines[2]);
      inc(i);
    end;
    
    CloseFile(studentFile);
    
    lines.Free();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-03
      • 1970-01-01
      • 2011-10-27
      • 1970-01-01
      相关资源
      最近更新 更多