将一组记录从文件加载回程序?

时间:2016-03-15 12:29:53

标签: lazarus freepascal

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

但是我现在希望将数据(StudentName,Class,Grade)重新加载到数组中,然后将它们显示在另一个表单的列表框中。

我尝试了一些方法但没有成功。

这是编写文件的代码:

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.                    

ScreenShot 1:StudentFile
ScreenShot 2:AddStudent Form

2 个答案:

答案 0 :(得分:2)

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

您可以定义仅包含最简单成员的记录,例如Ken White建议:

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

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

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;

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

如果你从一个记录移到另一个类,有更多有趣的可能性,在这种情况下,你可以使用流式系统,因为IDE将表格保存到光盘,.dfm或.lfm文件,所以你将成为能够自动保存复杂的对象层次并加载它们。

答案 1 :(得分:1)

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();