Delphi 5 problem with typed file - OK in Delphi 4

I have a program which saves and reads information using a typed file
It works without problems in Delphi 4 but in Delphi 5 it compiles and runs but seems to read the file wrongly.

The record type is
    THoliday = record
        name : string[40];
        dateBegins : TDateTime;
        dateEnds : TDateTime;
    end;

The code which fails is shown below and the point at which it crashes is given by the comment in the middle. The first few bytes in the first record, the name, are Ok but the dates are garbage:
procedure TfrmClassDates.FormCreate(Sender: TObject);
var
   HolData :THoliday;
   strName : string[42];
   strBegin : string[10];
   strEnd : string[10];
   strLine : string;
begin
   HolidayFileName := 'TheHOLS.BIN';
   AssignFile(HolidayFile, HolidayFileName);
   if FileExists(HolidayFileName) then
       begin
       Reset(HolidayFile); //open existing file
       HolCount := 0;
       isSaved := true;
       while not Eof(HolidayFile) do
           begin
           Read(HolidayFile, HolData);
           HolCount := HolCount + 1;
           HolArray[HolCount] := HolData;
           strName := HolData.name;
           strBegin := DateToStr(HolData.dateBegins);  

           // Program crashes at the line above
           // or the next line below with invalid floating point operation
           // only if compiled under Delphi 5 works fine with Delphi 4
           // debugger shows dateBegin values are garbage

           strEnd := DateToStr(HolData.dateEnds);
           strLine := format('%-14s %9s %9s',[strName,strBegin,strEnd]);
           lstHolidays.items.add(strLine);
           end;
       CloseFile(HolidayFile);
       dtpStartDate.DateTime := HolArray[1].dateEnds + 1;
       end
   else
       begin
       ShowMessage('Could not find the standard holiday file "theHols.bin"'
                     + #13#10 + ' in "H:\...\tutors\schedule"');
       end;
end;
seabearAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

simonetCommented:
Try this:

    THoliday = packed record
        name : string[40];
        dateBegins : TDateTime;
        dateEnds : TDateTime;
    end;

Yours,

Alex
0
simonetCommented:
You may also want to use ShortString instead of String on the TYPE definition.

Alex
0
seabearAuthor Commented:
Hi Alex
packed does not fix the problem, also I am dealing with existing files created without the packed clause.

How would I use shortstring to get a fixed string length of 40 bytes?
    name : shortstring[40];
gives a complier error "; expected [ found"

Dan
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

wimmeyvaertCommented:
Hi seabear,

I've written some delphi-programs who use text-files.
Those textfiles are of the Line-Sequential Type
(1 line = 1 record, each line is terminated with CR/LF).

What I do to access these files is the following :

1) Create a SCHEMA-File (= NameTextFile.SCH)
   This is a file who contains the record-description.
   This file is located in the same directory as your textfile +
   it must have the same name + extension SCH.
   The advantage of working with schema-files is that you can access
   textfiles like tables (without edit or delete functionality).
   For your file :
         [HOLIDAYS]
      FileType=FIXED
      Delimiter=
      Separator=
      CharSet=ascii
      Field1=Name,CHAR,40,0,0
      Field2=DateBegins,CHAR,10,0,40
      Field3=DateEnds,CHAR,10,0,50

2) In your application, you drop a table-component on your Form.
   2 properties must be set :
     A) TableType must be set to ASCII.
     B) TableName must be set to the location + name of the textfile.


3) Now on the FormCreate Event, you can put the following code to fill
   the contents of your ListBox :
      procedure TForm1.FormCreate(Sender: TObject);
      var
        strName  : String;
          strBegin : String;
          strEnd       : String;
          strLine       : String;
      begin
        With Table1 do
        begin
          Active := True; { Open Table (= TextFile) }
            First; {Goto first record }
            While not eof do
            begin
              strName  := FieldByName('Name').AsString;
              strBegin := FieldByName('DateBegins').AsString;
              strEnd   := FieldByName('DateEnds').AsString;
              strLine  := Format('%-14s %9s %9s',[strNAme,strBegin,strEnd]);
              ListBox1.Items.Add(strLine);
              Next; { Goto next record }
            end;
            Active := False; { Close Table (= TextFile) }
          end;
        end;


Maybe you can try this.
Hope it works.


Best regards,
The M@yor.
0
kretzschmarCommented:
hi seabear,

i see your problem
your record has a
packed size of 57 Bytes

in d4 the record will aligned to 60 Bytes

in d5  the record will aligned to 64 Bytes

i guess your records are created with a d4 app, and you will now access the records with d5

maybe a recordstructure like this helps

    THoliday = packed record  //no align
        name : string[40];
        Filler : String[2];   //fill three bytes
        dateBegins : TDateTime;
        dateEnds : TDateTime;
    end;


just not tested, but in d5 the record now have also 60 Bytes, maybe the filler is on the wrong place

meikl
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
rwilson032697Commented:
Try changing your record structure to this:

    THoliday = packed record
        name : string[40];
        Dummy : array[1..3] of byte// Suck up three bytes
        dateBegins : TDateTime;
        dateEnds : TDateTime;
    end;

Its a bit weird really, D5 appears to be padding two bytes after the two date fields, and I can't see way it should!

Cheers,

Raymond;
0
kretzschmarCommented:
hi raymond,
same idea ;-)
0
seabearAuthor Commented:
Thanks wimmeyvaert but I wanted a simple fix to allow me to read and edit exiting files created with D4. Your technique looks interesting though.



Note to Meikl and Raymond yep you've got it. This works fine

I shall reject the proposed answer then accept Meikl's comment as the answer since he got in first. (By one minute!!!!) Thanks to you both. If one of you has time could you tell me why this works? Why packed in D5 and not D4 and why the extra 3 bytes? Anyway thanks again - Dan
0
kretzschmarCommented:
hi dan,

first glad that this solves your problem,

well i try to explain,
in both delphi versions is the packed record-size of your original-recordstructure the same (57 Bytes).

as you coded in d4 you didn't use the keyword packed in the record-definition, therefore the compiler has aligned the recordstructure to 32Bit alignment for better performance by addressing the fields in the structure.

by doing this, the compiler left three bytes 'blank' between your string and the dates. the recordsize becomes 60 Bytes.

why in d5 now, additional 2 bytes are appended by the datefields, i don't know it, its against the alignment-philosophy, except the addressbus will become wider in near future.

well the idea from us both was, in d5 this alignment from d4 to do by hand, by avoiding the alignment with the keyword packed in the record-definition, and inserting 3 bytes after the string.

hope this explaination helps a little

meikl ;-)
0
seabearAuthor Commented:
Thanks Meikl that clears it up for me - Dan
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.