1

I am creating a program that moves through an array of records and save these student records to a file.

However I now wish to reload the data (StudentName,Class,Grade) back into the array and subsequently display them in a list box on another form.

I have tried a few methods but with no success.

This is the code that wrote the file:

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

animuson
  • 53,861
  • 28
  • 137
  • 147
P Grant
  • 31
  • 1
  • 8
  • 1
    Please add the content from your student file as text, not as a screenshot. It actually isn't that big and we won't be able to copy/paste from the image. – Sebastian Proske Mar 15 '16 at 12:32
  • 1
    What were the few methods you tried? What does "no success" mean? Were there errors? How did the result differ from what you expected? If you want the "best method", it's probably to use a database to store this information. – J... Mar 15 '16 at 12:32
  • 2
    Your `ClassGroup: string` will never work, because it has no defined length. You need to use `ShortString`, just like you did with `Name: string[30];`. With that said, a question that contains no clear problem statement (*I have tried a few methods with no success*) is extremely difficult to ask, and images should only be used for things that can't be demonstrated as text. Since your file is text, there's absolutely no reason to put it here in an image, and the image of your form is totally meaningless and irrelevant. If you want us to help, make it as easy as possible for us to do so. – Ken White Mar 15 '16 at 12:39
  • http://stackoverflow.com/q/35404596/4908529 – kami Mar 15 '16 at 12:48
  • what version of Delphi are you using? – Russell Weetch Mar 15 '16 at 13:37
  • @RussellWeetch `{$mode objfpc}{$H+}` ...it's obviously Lazarus – J... Mar 15 '16 at 14:04
  • apologies - grem error. should have looked at the code. – Russell Weetch Mar 15 '16 at 14:20

2 Answers2

2

Answer given by Zamrony P. Juhara is correct, but your approach here may be not the most convenient. You define record which contains information about each student, then you write procedures to write this record to file and another one to read it. If you'll eventually change format of your record, you'll have to rewrite this code also. There are better ways, in my opinion.

You can define record containing only simplest members, like Ken White suggested:

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

Such a record have fixed size and contains all needed information in itself (version with ClassGroup:String actually stores pointer to another area in memory where your string is), and then you can save and load it extremely easy:

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;

There is little drawback: file is not so readable as it was before, because Integer is saved exactly as 4-byte value, not its decimal representation.

There is much more interesting possibilities if you move from record to class, in that case you can use streaming system in a way as IDE saves forms to disc, in .dfm or .lfm files, so you'll be able to automatically save complex ierarchies of objects and load them back.

Yuriy Afanasenkov
  • 1,440
  • 8
  • 12
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();
Zamrony P. Juhara
  • 5,222
  • 2
  • 24
  • 40