Recent

Author Topic: need help with show a file like this  (Read 41732 times)

shobits1

  • Sr. Member
  • ****
  • Posts: 271
  • .
Re: need help with create a file like this
« Reply #45 on: September 27, 2015, 10:43:26 pm »
about the read/write date, it is encouraged to create two functions responsible of encoding and decoding the special date to pascal TDateTime, so you can read and write/update the file modification date easily and use pascal date functions.

Code: [Select]
function decode_date( sdate:word): TDateTime;
var
 year : integer;
 day, month, y_offset: byte;
begin
  y_offset := (sdate  AND %1111111000000000) shr 9;
  month    := (sdate AND  %0000000111100000) shr 5;
  day        := (sdate  AND %0000000000011111);
 
  if y_offset < 100 then
    year := 2000 + y_offset
 else
    year := 1999 - y_offset + 100;
 
  result := EncodeDate(year, month, day);
end;

function encode_date( stdate :TDateTime ) : word;
begin
  // do it yourself, not hard just inverted version of decode_date
  // hint: use DecodeDate( Date: TDateTime;  out Year: Word; out Month: Word; out Day: Word );


end;


Advice: imho, you need to learn more about the pascal basics and keep attention to details even if its small;
also remember members of this community will help you but not do your assignment, so try to re-read your TP(pdf file) many more times to understand the requirements more clearly; doing so I already learned a new thing about the file structure (even though using only google translate) and it is related to the records; you are handling the records in the wrong way/parially and only processing the case when length of the data greater then 0 and less then 255; you need to redesign how to process the records.

rvk

  • Hero Member
  • *****
  • Posts: 6704
Re: need help with create a file like this
« Reply #46 on: September 27, 2015, 10:47:17 pm »
I made this so that every time it checks Fields.Fieldnr (1,2,3 and/or 4) it writes its respective name and info.
but there's an error in it. is not taking "Fields.Fieldnr" correctly.
You made the same mistake as a few posts ago. (you should be able to correct this yourself)

Fields is an array-type. You can't do "Fields.Fieldnr of".

If you read the record in Rec you should use Rec.Fieldnr.

But your whole case construction is not needed. You SHOULDN'T use hardcoded fieldnames because the fieldnames are read from the file !!!!!!!

And you haven't read the FieldText yet. And FieldText isn't a variable in Field but in Rec.

So, first try to read a record before you're trying to print something to screen.

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with create a file like this
« Reply #47 on: September 27, 2015, 11:03:07 pm »
I keep forgeting that's an array.
the problem here is highlithed in green, right?
Code: [Select]
program Crear;
uses SysUtils;
type
  THeader = record
    Serial: Word;   //2 bytes
    Filename: String[255];  //1 byte
    Date: Word;  //2 bytes
    Fieldnrs: Word;  //2 bytes
    NrsRecords: Word;  //2 bytes
  end;
  TFields = record
    Fieldnr: Word;   //2 bytes
    Fieldname: String[255];   //1 byte
    FieldData: String[255]; //1 Byte
  end;
  TRecordField = record
    Fieldnr: Word;  //2 bytes
    FieldText: String[255];  //1 byte
  end;

var
  BinaryStream: File;
  Header: THeader;
  Fields: array [0..20] of TFields;
  Rec: array[0..20] of TRecordField;
  nrs: Integer;  //2 bytes

procedure myRead(var Buffer; Size: Integer);
  begin
    BlockRead(BinaryStream, Buffer, Size);
  end;

begin
  assign(BinaryStream, 'C:\Dev-Pas\EXAMEN2.dat');
  reset(BinaryStream, 1);
  myRead(Header.Serial, 2);
  myRead(Header.Filename[0], 1);
  myRead(Header.Filename[1], ord(Header.Filename[0]));
  myRead(Header.Date, 2);
  myRead(Header.Fieldnrs, 2);

  Header.Serial := Swap(Header.Serial);
  Header.Fieldnrs := Swap(Header.Fieldnrs);

  for nrs := 0 to Header.Fieldnrs - 1 do
  begin
       myRead (Fields[nrs].Fieldnr, 2);
       Fields[nrs].Fieldnr := Swap (Fields [nrs].Fieldnr);
       myRead (Fields[nrs].Fieldname[0],1);
       myRead (Fields[nrs].Fieldname[1], ord(Fields[nrs].Fieldname[0]));
  end;
       myRead(Header.NrsRecords, 2);
       Header.NrsRecords := Swap(Header.NrsRecords);

       Writeln ('Nro. de Serie: ', Header.Serial);
       Writeln ('Full Filename: ', Header.Filename);
       Writeln ('Fecha Modificacion: ', Header.Date);
       Writeln ('Cantidad de Campos Customizados: ', Header.Fieldnrs);

       for nrs := 0 to Header.Fieldnrs - 1 do
       begin
            Writeln ('Campo [codigo: ',Fields[nrs].Fieldnr,', ','descripcion: ',Fields[nrs].Fieldname ,']' );
       end;
       Writeln ('Cantidad de Registros: ', Header.NrsRecords);
       Writeln ('------------------------');


       myRead (Rec[nrs].Fieldnr, 2);
       myRead (Rec[nrs].FieldText, 1);
       for nrs := 0 to Header.NrsRecords - 1 do
       begin
            Writeln (Rec[nrs].Fieldnr,': ',Rec[nrs].FieldText);
       end;
       Writeln ('----[FIN CONTENIDO DEL ARCHIVO]-----------------');
Close(BinaryStream);
ReadLn;
end.
« Last Edit: September 27, 2015, 11:09:36 pm by GMP_47 »

rvk

  • Hero Member
  • *****
  • Posts: 6704
Re: need help with create a file like this
« Reply #48 on: September 27, 2015, 11:11:23 pm »
Again... you haven't learned from previous code.

First the nrs your using. That's a loop variable but your not in the loop where you point to. You need to create an additional loop to read all the fields from the first record.

Then the FieldText. You do myRead(Rec[_].FieldText, 1)
But like before... this is a string you need to read. Thus... first read the length in [] and then the characters.

Then the last remark.... you're still not following the stucture you've been fiven.

Look again at my pseudocode and look for the value you forgot to read:
Code: [Select]
Read NumberOfRecords
for/next 0 to NumberOfRecords - 1
begin
  Empty all fields (clear record Rec)
  Read NumberOfFieldsInRecord
  for/next 0 to NumberOfFieldsInRecord - 1
  begin
    Read Fieldnr
    Read stringlength
    Read Rec[Fieldnr].FieldText (stringlength characters)
  end;

  Printout record Rec

end;

« Last Edit: September 27, 2015, 11:14:09 pm by rvk »

shobits1

  • Sr. Member
  • ****
  • Posts: 271
  • .
Re: need help with create a file like this
« Reply #49 on: September 28, 2015, 12:04:48 am »
rvk, I applaud you for your patience.

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with create a file like this
« Reply #50 on: September 28, 2015, 12:21:15 am »
Code: [Select]
for I := 0 to Header.NrsRecords - 1 do
         begin
         myRead (Header.Fieldnrs, 2);

                for I := 0 to Header.Fieldnrs - 1 do
                begin
                     myRead (Rec[I].Fieldnr, 2);
                     myRead (Rec[I].FieldText[0], 1);
                     myRead (Rec[I].FieldText[1], ord(Rec[I].FieldText[0]));
                end;
         Writeln (Fields[Rec[I].Fieldnr].Fieldname,': ',Rec[Rec[I].Fieldnr].FieldText);
       end;
It doesnt show anything on the screen. my head really hurst so forgive me if I did bad.

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with create a file like this
« Reply #51 on: September 28, 2015, 12:21:51 am »
rvk, I applaud you for your patience.
yeah. we been here for 6 hours.

rvk

  • Hero Member
  • *****
  • Posts: 6704
Re: need help with create a file like this
« Reply #52 on: September 28, 2015, 12:22:25 am »
the problem here is highlithed in green, right?
Since you have some trouble with reading parts of the fields (like a string, first the number and then the characters themselves) maybe it's better to create some helper functions for you.

These functions are an extension on the myRead() I already gave you. It's myReadByte(), myReadWord() and myReadString(). Especially the last one (myReadString()) will help you because you can't seem to get that one right  ;D

Code: [Select]
procedure myRead(var Buffer; Size: Integer);
begin
  BlockRead(BinaryStream, Buffer, Size);
end;

procedure myReadByte(var B:Byte);
begin
  myRead(B, 1);
end;

procedure myReadWord(var W:Word);
begin
  myRead(W, 2);
  W := Swap(W);
end;

So now you can just read your given structure and use the myRead functions according to the fact if you need to read a Byte, Word of String.

The myReadWord already incorporates the swap() function so you can remove them in your main program if you use these functions.

rvk, I applaud you for your patience.
Thanks. Yeah, I've got a lot of experience in keeping my patience  :D

rvk

  • Hero Member
  • *****
  • Posts: 6704
Re: need help with create a file like this
« Reply #53 on: September 28, 2015, 12:30:12 am »
Code: [Select]
for I := 0 to Header.NrsRecords - 1 do
         begin
         myRead (Header.Fieldnrs, 2);

                for I := 0 to Header.Fieldnrs - 1 do
                begin
                     myRead (Rec[I].Fieldnr, 2);
                     myRead (Rec[I].FieldText[0], 1);
                     myRead (Rec[I].FieldText[1], ord(Rec[I].FieldText[0]));
                end;
         Writeln (Fields[Rec[I].Fieldnr].Fieldname,': ',Rec[Rec[I].Fieldnr].FieldText);
       end;
It doesnt show anything on the screen. my head really hurst so forgive me if I did bad.
Don't use the Header.Fieldnrs to read the number of fields in a record. You need to keep the Header.Fieldnrs for the Header.Fields which contain the fieldnames. Well... you don't actually need the Fieldnrs but it's best not to mess with it because it contains the maximum number of fields there possibly are.

And... You read in Header.Fieldnrs and Rec[_].Fieldnr but didn't do a swap().

If you use the function I gave you in the previous post the swap will be done automatically in myReadWord and you won't make that mistake again  :D

rvk

  • Hero Member
  • *****
  • Posts: 6704
Re: need help with create a file like this
« Reply #54 on: September 28, 2015, 12:35:25 am »
Second... look at this line:
Code: [Select]
         Writeln (Fields[Rec[I].Fieldnr].Fieldname,': ',Rec[Rec[I].Fieldnr].FieldText);
You're almost there... but...
You read in Rec[_].Fieldnr. The Fields are beginning with 0 in our Fields so you need to do
Fields[Rec[_].Fieldnr - 1].Fieldname

Then... What's this Rec[Rec[_].Fieldnr].FieldText. You've just read Rec[_].FieldText. Why not show that?  :D

And.... IEKS  :o You have a double loop both with the loop variable I !!! For the inner (or outer) loop use a different variable !!.


(I is replaced by _ here otherwise it would result in italic on the forum.)
« Last Edit: September 28, 2015, 12:42:34 am by rvk »

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with create a file like this
« Reply #55 on: September 28, 2015, 01:14:25 am »
These functions are an extension on the myRead() I already gave you. It's myReadByte(), myReadWord() and myReadString(). Especially the last one (myReadString()) will help you because you can't seem to get that one right
It's like this?
Code: [Select]
procedure myReadString(var S:String);
begin
  myRead(S,1);
end;

Quote
Then... What's this Rec[Rec[_].Fieldnr].FieldText. You've just read Rec[_].FieldText. Why not show that?  :D
um... what?
« Last Edit: September 28, 2015, 01:19:26 am by GMP_47 »

rvk

  • Hero Member
  • *****
  • Posts: 6704
Re: need help with create a file like this
« Reply #56 on: September 28, 2015, 01:19:06 am »
These functions are an extension on the myRead() I already gave you. It's myReadByte(), myReadWord() and myReadString(). Especially the last one (myReadString()) will help you because you can't seem to get that one right
It's like this?
No no. The String is a short string. It's also a shortstring in the file.
So the procedure are like I showed you and you can use 'em like this:
Code: [Select]
  assign(BinaryStream, 'C:\Dev-Pas\EXAMEN2.dat');
  reset(BinaryStream, 1);
  myReadWord(Header.Serial);
  myReadString(Header.Filename);
  myReadWord(Header.Date);
  myReadWord(Header.Fieldnrs);
  for nrs := 0 to Header.Fieldnrs - 1 do
  begin
     myReadWord(Fields[nrs].Fieldnr);
     myReadString(Fields[nrs].Fieldname);
  end;
  myReadWord(Header.NrsRecords);
  // etc....
(see the myReadString. The Header.Filename needs to stay a ShortString or String[255])

Advantage is that you don't need to read the length-byte and characters separate anymore. That's done in the procedure I gave you. Also the myReadWord does the swap for you. So you don't need to do the swap after using myReadWord.
« Last Edit: September 28, 2015, 01:22:07 am by rvk »

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with create a file like this
« Reply #57 on: September 28, 2015, 01:21:06 am »
These functions are an extension on the myRead() I already gave you. It's myReadByte(), myReadWord() and myReadString(). Especially the last one (myReadString()) will help you because you can't seem to get that one right
It's like this?
No no. The String is a short string. It's also a shortstring in the file.
So the procedure are like I showed you and you can use 'em like this:
Code: [Select]
  assign(BinaryStream, 'C:\Dev-Pas\EXAMEN2.dat');
  reset(BinaryStream, 1);
  myReadWord(Header.Serial);
  myReadString(Header.Filename);
  myReadWord(Header.Date);
  myReadWord(Header.Fieldnrs);
(see the myReadString. The Header.Filename needs to stay a ShortString or String[255])

Advantage is that you don't need to read the length-byte and characters separate anymore. That's done in the procedure I gave you. Also the myReadWord does the swap for you. So you don't need to do the swap after using myReadWord.

but there was no myReadString in your post.

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with create a file like this
« Reply #58 on: September 28, 2015, 01:23:29 am »
bloodshed is also giving me error in each myRead

rvk

  • Hero Member
  • *****
  • Posts: 6704
Re: need help with create a file like this
« Reply #59 on: September 28, 2015, 01:23:45 am »
Woops  %) sorry. That one seemed to be cut off during my copy and paste.
Here it is again:
Code: [Select]
procedure myRead(var Buffer; Size: Integer);
begin
  BlockRead(BinaryStream, Buffer, Size);
end;

procedure myReadByte(var B:Byte);
begin
  myRead(B, 1);
end;

procedure myReadWord(var W:Word);
begin
  myRead(W, 2);
  W := Swap(W);
end;

procedure myReadString(var S:ShortString);
var
  Len: Byte;
begin
  myRead(Len, 1);
  S[0] := Chr(Len);
  myRead(S[1], Len);
end;

 

TinyPortal © 2005-2018