Recent

Author Topic: need help with creating a file like this  (Read 15029 times)

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with creating a file like this
« Reply #15 on: October 12, 2015, 06:05:55 pm »
I made all possible vars local. In "function encode_date : Word;" it's giving error Local variable YEAR/MONTH/DAY does not seem to be initialized but I included those in the local function var:


Code: Pascal  [Select][+][-]
  1. program Crear;
  2. uses SysUtils;
  3. type
  4.   THeader = record
  5.     Serial: Word;   //2 bytes
  6.     Filename: String[255];  //1 byte
  7.     Date: Word;  //2 bytes
  8.     Fieldnrs: Word;  //2 bytes
  9.     NrsRecords: Word;  //2 bytes
  10.   end;
  11.   TFields = record
  12.     Fieldnr: Word;   //2 bytes
  13.     Fieldname: ShortString;   //1 byte
  14.   end;
  15.   TRecordField = record
  16.     Fieldnr: Word;  //2 bytes
  17.     FieldText: String[255];  //1 byte
  18.   end;
  19.   TDateTime = double;
  20.  
  21. var
  22.   BinaryStream: File;
  23.   Header: THeader;                     //Header.Serial Filename Date Fieldnrs NrsRecords
  24.   Fields: array [0..20] of TFields;    //Fields.Fieldnr     Fields.Fieldname
  25.   Rec: array[0..20] of TRecordField;   //Rec.Fieldnr        Rec.FieldText
  26.   nrs: Integer;  //2 bytes
  27.   I,N,J: Integer;
  28.  
  29. procedure myWrite (var Buffer; Size: Integer);
  30. begin
  31.      BlockWrite(BinaryStream, Buffer, Size);
  32. end;
  33.  
  34. procedure myWriteWord (var W:Word);
  35. begin
  36.      W := Swap(W);
  37.      myWrite(W,2);
  38. end;
  39.  
  40.  
  41. procedure myWriteString (var S:ShortString);
  42. var
  43.    Len: Byte;
  44. begin
  45.      Len := Length(S);
  46.      myWrite (Len,1);
  47.      myWrite (S[1], Len);
  48. end;
  49.  
  50.  
  51.  
  52. function encode_date : Word;
  53. var
  54.    Year,Month,Day,y_offset: Word;
  55. begin
  56.      if Year > 2000 then begin
  57.           y_offset :=  year - 2000;
  58.         end else begin
  59.           y_offset := 2099 - year;
  60.      end;
  61.      result := y_offset  shl 9;
  62.      result := result + Month  shl 5;
  63.      result := result + Day
  64. end;
  65.  
  66. begin
  67.      assign(BinaryStream, 'C:\Dev-Pas\EXAMEN333.dat');
  68.      rewrite(BinaryStream, 1);
  69.  
  70.      Writeln ('Ingrese Serial:');                   //serial
  71.      ReadLn (Header.Serial);
  72.      myWriteWord (Header.Serial);
  73.  
  74.      Writeln ('Ingrese Nombre Archivo:');           //path
  75.      ReadLn (Header.Filename);
  76.      myWriteString (Header.Filename);
  77.                                                     //fecha
  78.      Header.Date := encode_date;
  79.      myWriteWord (Header.Date);
  80.  
  81.      Writeln ('Ingrese Cantidad de Campos Customizados:');      //campos custom
  82.      ReadLn (Header.Fieldnrs);
  83.      myWriteWord (Header.Fieldnrs);
  84.  
  85.  
  86.      for nrs := 1  to Header.Fieldnrs  do                   //codigo 1,2,3,4
  87.      begin
  88.           myWriteWord (Fields[nrs].Fieldnr);                //nombre,tel,dir,email
  89.           Writeln ('Ingrese Nombre de dato numero:', nrs);
  90.           ReadLn (Fields[nrs].Fieldname);
  91.           myWriteString (Fields[nrs].Fieldname);
  92.      end;
  93.  
  94.      Writeln ('Ingrese la cantidad de registros:');   //cantidad de registros
  95.      ReadLn (Header.NrsRecords);
  96.      myWriteWord (Header.NrsRecords);
  97.  
  98.      Writeln ('Ingrese los ',Header.NrsRecords,'contactos');    //datos contactos concretos
  99.  
  100.  
  101.      for J := 1 to Header.NrsRecords do
  102.      begin
  103.  
  104.           for I := 1 to Header.Fieldnrs do
  105.           begin
  106.  
  107.               Writeln ('Ingrese:', Fields[I].Fieldname);
  108.               ReadLn (Rec[I].FieldText);
  109.                  if Length (Rec[I].FieldText) <> 0 then begin
  110.                         if Length (Rec[I].FieldText) < 255 then begin
  111.                                myWriteString (Rec[I].FieldText);
  112.                            end else begin
  113.                                Writeln ('Debe ser Menos de 255 caracteres');
  114.                         end;
  115.  
  116.                     end;
  117.           end;
  118.      end;
  119. myWriteWord (Header.NrsRecords := cant_reg );
  120. close (BinaryStream);
  121. end.

rvk

  • Hero Member
  • *****
  • Posts: 6944
Re: need help with creating a file like this
« Reply #16 on: October 12, 2015, 06:12:06 pm »
I made all possible vars local. In "function encode_date : Word;" it's giving error Local variable YEAR/MONTH/DAY does not seem to be initialized but I included those in the local function var:
You still need the DecodeDate() line in your encode_date to get the year, month and day from the Date-function. (Didn't you see that?)

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with creating a file like this
« Reply #17 on: October 12, 2015, 07:00:59 pm »
It compiles. I created EXAMEN333.dat but I use MOSTRAR.pas to show it on screen.
I didnt write anything above 255 units.

rvk

  • Hero Member
  • *****
  • Posts: 6944
Re: need help with creating a file like this
« Reply #18 on: October 12, 2015, 07:14:52 pm »
I'm not sure what you mean by 255 units.
But... look at your code.
You know the structure of the file.
Now go through the main code and look at all the myWrite parts.

Can you tell me which myWrite-parts you are missing?

Second is the writing of myWriteWord (Fields[nrs].Fieldnr);.
I already gave you a hint that Fields[nrs].Fieldnr isn't initialized.
Before writing it to disk you need to fill in Fieldnr.

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with creating a file like this
« Reply #19 on: October 12, 2015, 08:20:53 pm »
Can you tell me which myWrite-parts you are missing?

No. not sure I get the question.

Code: Pascal  [Select][+][-]
  1. for nrs := 1  to N   do                   //codigo 1,2,3,4
  2.      begin
  3.           Fields[nrs].Fieldnr := nrs;
  4.           myWriteWord (Fields[nrs].Fieldnr);                //nombre,tel,dir,email
  5.           Writeln ('Ingrese Nombre de dato numero:', nrs);
  6.           ReadLn (Fields[nrs].Fieldname);
  7.           myWriteString (Fields[nrs].Fieldname);
  8.      end;

rvk

  • Hero Member
  • *****
  • Posts: 6944
Re: need help with creating a file like this
« Reply #20 on: October 12, 2015, 08:28:49 pm »
Can you tell me which myWrite-parts you are missing?

No. not sure I get the question.

Code: Pascal  [Select][+][-]
  1. for nrs := 1  to N   do                   //codigo 1,2,3,4
  2.      begin
  3.           Fields[nrs].Fieldnr := nrs;
  4.           myWriteWord (Fields[nrs].Fieldnr);                //nombre,tel,dir,email
  5.           Writeln ('Ingrese Nombre de dato numero:', nrs);
  6.           ReadLn (Fields[nrs].Fieldname);
  7.           myWriteString (Fields[nrs].Fieldname);
  8.      end;
Well, that part you fixed now.

Now I'm talking about this part:
Code: Pascal  [Select][+][-]
  1. for J := 1 to NR do
  2. begin
  3.   for I := 1 to N do
  4.   begin
  5.     Writeln ('Ingrese:', Fields[I].Fieldname);
  6.     ReadLn (Rec[I].FieldText);
  7.     if Length (Rec[I].FieldText) <> 0 then begin
  8.       if Length (Rec[I].FieldText) < 255 then begin
  9.         myWriteString (Rec[I].FieldText);
  10.       end else begin
  11.         Writeln ('Debe ser Menos de 255 caracteres');
  12.       end;
  13.     end;
  14.   end;
  15. end;

Look at what is written for every record.
And now see what you write.
Your missing something.

One other thing you missed. Before every record there is a word written with the number of fields you write in the following record. So you first need to completely read the fields from the user. After that you need to count the number of fields you are about to write. Write that number to disk and then write the fields themselves.

So unfortunately you need to rewrite the complete last (inner) for loop and split it into two loops. One for reading Rec[0..N-1] from the user. Then write the number of filled in fields. And another loop of really writing these fields.

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with creating a file like this
« Reply #21 on: October 12, 2015, 09:33:39 pm »
but it worked. it was asking me to fill the FieldText with their respective FieldText.
double desition: if the field is empty (length=0) does nothing and goes to the next I.
added a "I := I - 1;" so the I doesnt go up once someone messes up the String.

Code: Pascal  [Select][+][-]
  1. Writeln ('Ingrese los ',NR,' contactos');    //datos contactos concretos
  2.      for J := 1 to NR do
  3.      begin
  4.           for I := 1 to N do
  5.           begin
  6.               Writeln ('Ingrese:', Fields[I].Fieldname);
  7.               ReadLn (Rec[I].FieldText);
  8.                  if Length (Rec[I].FieldText) <> 0 then begin
  9.                         if Length (Rec[I].FieldText) < 255 then begin
  10.                                myWriteString (Rec[I].FieldText);
  11.                            end else begin
  12.                                Writeln ('Debe ser Menos de 255 caracteres');
  13.                                I := I - 1;
  14.                         end;
  15.                  end;
  16.           end;
  17.      end;
this is not the same structure as the other file? that's why SHOW.pas isnt compiling?

rvk

  • Hero Member
  • *****
  • Posts: 6944
Re: need help with creating a file like this
« Reply #22 on: October 12, 2015, 10:47:40 pm »
but it worked. it was asking me to fill the FieldText with their respective FieldText.
Yes, it worked. It asks you the input. But is doesn't write the correct things to disk.

Make a list of the fields (physical bytes as instructed in your assignment) which need to be in a records (per contact) and put it here. Next make a list of the fields you write in your code and put it here. You'll automatically see what you're missing.

if the field is empty (length=0) does nothing and goes to the next I.
added a "I := I - 1;" so the I doesnt go up once someone messes up the String.
This was the least of you worries.
I, personally, would have done this with a repeat/until around the input so you wouldn't have to manipulate a for/next variable, but this way works too.

Still, you need to look at the other things a said before you can read this data-file back with your read-code.

this is not the same structure as the other file? that's why SHOW.pas isnt compiling?
No, your structure is not complete.
And what do you mean SHOW.pas isn't compiling? I thought you had that working?
If your right the SHOW.pas is compiling but isn't reading your written file correctly because your structure isn't correct/complete.
« Last Edit: October 12, 2015, 10:49:32 pm by rvk »

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with creating a file like this
« Reply #23 on: October 12, 2015, 11:28:07 pm »
Quote
Make a list of the fields (physical bytes as instructed in your assignment) which need to be in a records (per contact) and put it here. Next make a list of the fields you write in your code and put it here. You'll automatically see what you're missing.

in RegData; 2 Bytes: Cantidad de Campos completos (amount of filled fields such as name tel adress and Email).
that's what I'm missing here, right?
ex:
(fields:4)
Nombre: Rogelio Roldan
Telefono: 4532-2411
Direccion: Rulo 126
EMail: roge@roldan.com.ar
-----------------------
(fields:3)
Nombre: Mongo Piccio
Telefono: 4223-2345
EMail: mongo@piccio.com.uy
« Last Edit: October 12, 2015, 11:30:54 pm by GMP_47 »

rvk

  • Hero Member
  • *****
  • Posts: 6944
Re: need help with creating a file like this
« Reply #24 on: October 12, 2015, 11:32:46 pm »
in RegData; 2 Bytes: Cantidad de Campos completos (amount of filled fields such as name tel adress and Email).
that's what I'm missing here, right?
That's one of them.
For this one, to be able to write it at the beginning of the record, I advised you to first read the fields from the user and then write the number of filled in fields and then the actual fields.

But you're missing another. Look at what you need to write per field. You write the string. But something before that.

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with creating a file like this
« Reply #25 on: October 13, 2015, 12:02:48 am »
Quote
For this one, to be able to write it at the beginning of the record, I advised you to first read the fields from the user and then write the number of filled in fields and then the actual fields.


Code: Pascal  [Select][+][-]
  1. Writeln ('Ingrese los ',NR,' contactos');    //datos contactos concretos
  2.      for J := 1 to NR do
  3.      begin
  4.           for I := 1 to N do
  5.           begin
  6.                Writeln ('Ingrese:', Fields[I].Fieldname);
  7.                ReadLn (Rec[I].FieldText);
  8.                if Length (Rec[I].FieldText) <> 0 then begin
  9.                  Camp:=(Camp+1);
  10.                  end;
  11.                Rec[C].FullField := Camp;
  12.                myWriteWord ( Rec[C].FullField );
  13.           end;
  14.  
  15.           for C := 1 to Camp do
  16.           begin
  17.                     myWriteString (Rec[C].FieldText);
  18.           end;
  19.      end;

did that do it?
« Last Edit: October 13, 2015, 12:14:02 am by GMP_47 »

rvk

  • Hero Member
  • *****
  • Posts: 6944
Re: need help with creating a file like this
« Reply #26 on: October 13, 2015, 12:15:32 am »
did that do it?
Not quite (but almost).

You don't need to store Camp into an extra field FullField. You can just use Camp directly to write to disk. But you need to write the final value of Camp. Now you write every value of Camp (within the loop). You need to write it outside/after the first loop.

Next... What do you think happens to Camp when you get to the second contact? Don't you need to reset that value?

And finally, you're still missing an important piece in front of each string you write.

Also, the second loop isn't the same as the first. Are you sure the correct filled in fields are written to disk? Look closely and if you're unsure print out the fields you're writing to display so you can see what you're writing. (Hint: the second loop need to be almost identical to the first with the exception that you don't need to increment Camp but do need to write the correct field)

And again... Make a list of the bytes you need to write and make a list of the bytes you're writing now. See the difference?
« Last Edit: October 13, 2015, 12:23:20 am by rvk »

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with creating a file like this
« Reply #27 on: October 13, 2015, 12:36:12 am »
Quote
Again... Make a list of the bytes you need to write and make a list of the bytes you're writing now. See the difference?

In the whole main or in the nested FORs? I dont get it. I'm writting in bigger amounts of Bytes?

Code: Pascal  [Select][+][-]
  1. program Crear;
  2. uses SysUtils;
  3. type
  4.   THeader = record
  5.     Serial: Word;   //2 bytes
  6.     Filename: String[255];  //1 byte
  7.     Date: Word;  //2 bytes
  8.     Fieldnrs: Word;  //2 bytes
  9.     NrsRecords: Word;  //2 bytes
  10.   end;
  11.   TFields = record
  12.     Fieldnr: Word;   //2 bytes
  13.     Fieldname: ShortString;   //1 byte
  14.   end;
  15.   TRecordField = record
  16.     FullField: Word;
  17.     Fieldnr: Word;  //2 bytes
  18.     FieldText: String[255];  //1 byte
  19.   end;
  20.  
  21. var
  22.   BinaryStream: File;
  23.   Header: THeader;                     //Header.Serial Filename Date Fieldnrs NrsRecords
  24.   Fields: array [0..20] of TFields;    //Fields.Fieldnr     Fields.Fieldname
  25.   Rec: array[0..20] of TRecordField;   //Rec.Fieldnr        Rec.FieldText
  26.   nrs: Integer;  //2 bytes
  27.   I,N,J,C,NR,Camp: Integer;
  28.  
  29. procedure myWrite (var Buffer; Size: Integer);
  30. begin
  31.      BlockWrite(BinaryStream, Buffer, Size);
  32. end;
  33.  
  34. procedure myWriteWord (var W:Word);
  35. begin
  36.      W := Swap(W);
  37.      myWrite(W,2);
  38. end;
  39.  
  40.  
  41. procedure myWriteString (var S:ShortString);
  42. var
  43.    Len: Byte;
  44. begin
  45.      Len := Length(S);
  46.      myWrite (Len,1);
  47.      myWrite (S[1], Len);
  48. end;
  49.  
  50.  
  51.  
  52. function encode_date : Word;
  53. var
  54.    Year,Month,Day,y_offset: Word;
  55. begin
  56.      DeCodeDate (Date,Year,Month,Day);
  57.      if Year > 2000 then begin
  58.           y_offset :=  year - 2000;
  59.         end else begin
  60.           y_offset := 2099 - year;
  61.      end;
  62.      result := y_offset  shl 9;
  63.      result := result + Month  shl 5;
  64.      result := result + Day
  65. end;
  66.  
  67. begin
  68.      assign(BinaryStream, 'C:\Dev-Pas\EXAMEN333.dat');
  69.      rewrite(BinaryStream, 1);
  70.  
  71.      Writeln ('Ingrese Serial:');                   //serial
  72.      ReadLn (Header.Serial);
  73.      myWriteWord (Header.Serial);
  74.  
  75.      Writeln ('Ingrese Nombre Archivo:');           //path
  76.      ReadLn (Header.Filename);
  77.      myWriteString (Header.Filename);
  78.                                                     //fecha
  79.      Header.Date := encode_date;
  80.      myWriteWord (Header.Date);
  81.  
  82.      Writeln ('Ingrese Cantidad de Campos Customizados:');      //campos custom
  83.      ReadLn (Header.Fieldnrs);
  84.      N:=Header.Fieldnrs;
  85.      myWriteWord (Header.Fieldnrs);
  86.  
  87.  
  88.      for nrs := 1  to N   do                   //codigo 1,2,3,4
  89.      begin
  90.           Fields[nrs].Fieldnr := nrs;
  91.           myWriteWord (Fields[nrs].Fieldnr);                //nombre,tel,dir,email
  92.           Writeln ('Ingrese Nombre de dato numero:', nrs);
  93.           ReadLn (Fields[nrs].Fieldname);
  94.           myWriteString (Fields[nrs].Fieldname);
  95.      end;
  96.  
  97.      Writeln ('Ingrese la cantidad de registros:');   //cantidad de registros
  98.      ReadLn (Header.NrsRecords);
  99.      NR:=Header.NrsRecords;
  100.      myWriteWord (Header.NrsRecords);
  101.  
  102.      Writeln ('Ingrese los ',NR,' contactos');    //datos contactos concretos
  103.      for J := 1 to NR do
  104.      begin
  105.           for I := 1 to N do
  106.           begin
  107.                Writeln ('Ingrese:', Fields[I].Fieldname);
  108.                ReadLn (Rec[I].FieldText);
  109.                if Length (Rec[I].FieldText) <> 0 then begin
  110.                  Camp:=(Camp+1);
  111.                  end;
  112.           end;
  113.  
  114.           Rec[J].FullField := Camp;
  115.           myWriteWord ( Rec[J].FullField );
  116.  
  117.           for C := 1 to Camp do
  118.           begin
  119.                myWriteString ( Rec[C].FieldText );
  120.           end;
  121.           Camp := 0 ;
  122.      end;
  123. close (BinaryStream);
  124. end.

rvk

  • Hero Member
  • *****
  • Posts: 6944
Re: need help with creating a file like this
« Reply #28 on: October 13, 2015, 12:45:47 am »
Quote
Again... Make a list of the bytes you need to write and make a list of the bytes you're writing now. See the difference?
In the whole main or in the nested FORs? I dont get it. I'm writting in bigger amounts of Bytes?
You need too make a list of the bytes you write within the "for j" loop. One iteration of j is one contact. See what your actually writing.

Also... I thought you had Camp declared as Word. The fullfield will only confuse you. Remove the fullfield field and make Camp a Word and do a myWriteWord(Camp) outside the loop like you do now for fullfield.

Next look at the construction of both inner loops and see if you're writing the correct field in the second loop. (Are you?)

Finally make that list of bytes you need in the record structrure and see which bytes you're still missing.

B.T.W. Did you test if you give 0 contracts to write  if you can read the file with you show.pas? If so, then you're sure the first part is correct.
« Last Edit: October 13, 2015, 12:49:20 am by rvk »

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with creating a file like this
« Reply #29 on: October 13, 2015, 01:06:32 am »
Quote
B.T.W. Did you test if you give 0 contracts to write  if you can read the file with you show.pas? If so, then you're sure the first part is correct.

SHOW.pas is fine. It compiles with the .dat given. but When I create a .dat with CREATE.pas, SHOW.pas crashes (it compiles but doesnt do anything.)

Code: Pascal  [Select][+][-]
  1. Writeln ('Ingrese los ',NR,' contactos');    //datos contactos concretos
  2.      for J := 1 to NR do
  3.      begin
  4.           for I := 1 to N do
  5.           begin
  6.                Writeln ('Ingrese:', Fields[I].Fieldname);
  7.                ReadLn (Rec[I].FieldText);
  8.                if Length (Rec[I].FieldText) <> 0 then begin
  9.                  Camp:=(Camp+1);
  10.                  end;
  11.           end;
  12.  
  13.           myWriteWord(Camp);
  14.  
  15.           for C := 1 to Camp do
  16.           begin
  17.                Rec[C].Fieldnr := C;
  18.                myWriteWord   ( Rec[C].Fieldnr );
  19.                myWriteString ( Rec[C].FieldText );
  20.           end;
  21.           Camp := 0 ;
  22.      end;

 

TinyPortal © 2005-2018