Recent

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

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with create a file like this
« Reply #60 on: September 28, 2015, 01:32:21 am »
it's giving Error: Wrong amount of parameters specified on each use of
Code: [Select]
myReadWord(Header.Serial, 2);
  myReadString(Header.Filename[0], 1);
  myReadString(Header.Filename[1], ord(Header.Filename[0]));
  myReadWord(Header.Date, 2);
  myReadWord(Header.Fieldnrs, 2);

shobits1

  • Sr. Member
  • ****
  • Posts: 271
  • .
Re: need help with create a file like this
« Reply #61 on: September 28, 2015, 01:33:36 am »
GMP_47, I already told you that there is a flou in the implementation, and that is assuming the length of the string will always be 0<length<255; but in the pdf file you attached is clearly stating that to handle the
data length = 0 or > 255; file structure should e altered slightly;

in general your defined type should be like (according to the pdf file)
Code: [Select]
Type
  CString = record  //need special function to facilitate string processing
    flag: byte;         // needed when data length=0 or >255
    length: word;    // not used when data length=0
    data: string;     //  dynamic length | not used when data length=0
  end;

  TRegType = record
     field_id: word;            //
     Description: CString;  //
  end;
 
  TRegData = record
     field_count_in_record: word;            //
     field_in_record: array of TRegType;  //
  end;

var
  serial : word;                        //
  path  : CString;                     //
  Date  : word;                        //need special function to decode
  field_count: word;                //
  fields: array of TRegType;    //dynamic allocation size = field_count
  record_count: word;            //used to loop through all available records.
  record: TRegData;               //only one record is read at any moment.

I suspect using classes will make the code cleaner and easier to understand; and I think CString, TRegType, TRegData should be classes rather than records so each can handle the dynamic nature of it's data.

rvk

  • Hero Member
  • *****
  • Posts: 6684
Re: need help with create a file like this
« Reply #62 on: September 28, 2015, 01:41:51 am »
it's giving Error: Wrong amount of parameters specified on each use of
Code: [Select]
myReadWord(Header.Serial, 2);
  myReadString(Header.Filename[0], 1);
  myReadString(Header.Filename[1], ord(Header.Filename[0]));
  myReadWord(Header.Date, 2);
  myReadWord(Header.Fieldnrs, 2);
I gave you some examples as how to use it. The second parameter isn't needed because the function already knows how many bytes it needs to read.

GMP_47, I already told you that there is a flou in the implementation, and that is assuming the length of the string will always be 0<length<255; but in the pdf file you attached is clearly stating that to handle the
data length = 0 or > 255; file structure should e altered slightly;
Although I agree with you that this could be better done with classes it seems that's too complicated for GMP_47.

But you say in the PDF the string could be >255 characters? Where do you read that? The string-type in the file has only one byte for the length so it can't be >255. CString is realy a ShortString here. (Look in the given file) The "Código del campo" you see in the pdf is the field-number. So the number of possible fields could exceed 255. But as FPC 1.0.6 doesn't even have the possibility of dynamic arrays, I think working with complete classes could be a challenge.

The PDF also says this:
Quote
CString
Representa una cadena de caracteres cuya estructura interna dependerá de su longitud. Sea L la longitud de la cadena, entonces:
Si 0<L<255 entonces:

Translation:
Quote
CString
It represents a character string whose internal structure will depend on its length. Let L the length of the string, then:
If 0 <L <255 then:

So no, CString is always 0 to 255 characters.
« Last Edit: September 28, 2015, 01:47:14 am by rvk »

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: need help with create a file like this
« Reply #63 on: September 28, 2015, 01:43:22 am »
Quote
rvk wrote:
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;

Quote
GMP_47 wrote:

it's giving Error: Wrong amount of parameters specified on each use of

Code: [Select]
myReadWord(Header.Serial, 2);
  myReadString(Header.Filename[0], 1);
  myReadString(Header.Filename[1], ord(Header.Filename[0]));
  myReadWord(Header.Date, 2);
  myReadWord(Header.Fieldnrs, 2);

Now, please take a good look at rvk's MyReadWord Function. How many parameters does it accept ?
Quote
procedure myReadWord(var W:Word);

And how many parameters are you supplying ?
Quote
myReadWord(Header.Serial, 2);

If you can answer that, then you've learned what the compiler meant by "Wrong amount of parameters specified"  :)

(and hopefully you'll be able to correct the others as well)

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with create a file like this
« Reply #64 on: September 28, 2015, 01:48:28 am »
Quote
rvk wrote:
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;

Quote
GMP_47 wrote:

it's giving Error: Wrong amount of parameters specified on each use of

Code: [Select]
myReadWord(Header.Serial, 2);
  myReadString(Header.Filename[0], 1);
  myReadString(Header.Filename[1], ord(Header.Filename[0]));
  myReadWord(Header.Date, 2);
  myReadWord(Header.Fieldnrs, 2);

Now, please take a good look at rvk's MyReadWord Function. How many parameters does it accept ?
Quote
procedure myReadWord(var W:Word);

And how many parameters are you supplying ?
Quote
myReadWord(Header.Serial, 2);

If you can answer that, then you've learned what the compiler meant by "Wrong amount of parameters specified"  :)

(and hopefully you'll be able to correct the others as well)
I did.
if L>=255 gives back a flag, Int and Char. but I rather not use that.

rvk

  • Hero Member
  • *****
  • Posts: 6684
Re: need help with create a file like this
« Reply #65 on: September 28, 2015, 01:51:28 am »
Look again at my example code in this post:
http://forum.lazarus.freepascal.org/index.php/topic,29740.msg188718.html#msg188718

There is also no need to separately read the FileName[0] because that's done in myReadString.

it will result in much cleaner code.

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with create a file like this
« Reply #66 on: September 28, 2015, 01:51:50 am »
I got lost, I dont remember what I was doing.
It compiles but nothing is shown.
I wasnt supposed to use myReadWord (Header.Fieldnrs); am guessing...
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: ShortString;   //1 byte
  end;
  TRecordField = record
    Fieldnr: Word;  //2 bytes
    FieldText: String[255];  //1 byte
  end;

var
  BinaryStream: File;
  Header: THeader;                     //Header.Serial Filename Date Fieldnrs NrsRecords
  Fields: array [0..20] of TFields;    //Fields.Fieldnr     Fields.Fieldname
  Rec: array[0..20] of TRecordField;   //Rec.Fieldnr        Rec.FieldText
  Len: Byte;
  nrs: Integer;  //2 bytes
  I,N: Integer;

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

begin
  myRead(Len, 1);
  S[0] := Chr(Len);
  myRead(S[1], Len);
end;


begin
  assign(BinaryStream, 'C:\Dev-Pas\EXAMEN2.dat');
  reset(BinaryStream, 1);
  myReadWord(Header.Serial);
  myReadString(Header.Filename);

  myReadWord(Header.Date);
  myReadWord(Header.Fieldnrs);

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

       for N := 0 to Header.NrsRecords - 1 do
         begin
         myReadWord (Header.Fieldnrs);

                for I := 0 to Header.Fieldnrs - 1 do
                begin
                     myReadWord (Rec[I].Fieldnr);
                     myReadString (Rec[I].FieldText);
                end;
         Writeln (Fields[Rec[I].Fieldnr - 1].Fieldname,': ',Rec[Rec[I].Fieldnr].FieldText);
       end;
Writeln ('----[FIN CONTENIDO DEL ARCHIVO]-----------------');
Close(BinaryStream);
ReadLn;
end.

rvk

  • Hero Member
  • *****
  • Posts: 6684
Re: need help with create a file like this
« Reply #67 on: September 28, 2015, 01:56:39 am »
I got lost, I dont remember what I was doing.
It compiles but nothing is shown.
I wasnt supposed to use myReadWord (Header.Fieldnrs); am guessing...
Yes, you were... But as I already said: I implemented the swap() in myReadWord already so you don't need to do the swap in your main code. Remove all the swaps there.

And lastly... this line:
Code: [Select]
Writeln (Fields[Rec[I].Fieldnr - 1].Fieldname,': ',Rec[Rec[I].Fieldnr].FieldText);
You just read in this line:
Code: [Select]
myReadString (Rec[I].FieldText);

So... what is filled in this????
Code: [Select]
Rec[Rec[I].Fieldnr].FieldText

You could just print out
Code: [Select]
Rec[I].FieldText

Now move the writeln inside the inner-loop and your done  :D

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: need help with create a file like this
« Reply #68 on: September 28, 2015, 01:57:50 am »
@GMP_47 @rvk
I'll refrain from further interfering, otherwise i'll only add to GMP_47's confusion.

@rvk
i jumped in as i thought you had called it a day (or night for that matter). Either there is an angel on your shoulder  or you are one yourself :bows:

shobits1

  • Sr. Member
  • ****
  • Posts: 271
  • .
Re: need help with create a file like this
« Reply #69 on: September 28, 2015, 02:04:48 am »
Although I agree with you that this could be better done with classes it seems that's too complicated for GMP_47.

But you say in the PDF the string could be >255 characters? Where do you read that? The string-type in the file has only one byte for the length so it can't be >255. CString is realy a ShortString here. (Look in the given file) The "Código del campo" you see in the pdf is the field-number. So the number of possible fields could exceed 255. But as FPC 1.0.6 doesn't even have the possibility of dynamic arrays, I think working with complete classes could be a challenge.

The PDF also says this:
Quote
CString
Representa una cadena de caracteres cuya estructura interna dependerá de su longitud. Sea L la longitud de la cadena, entonces:
Si 0<L<255 entonces:

Translation:
Quote
CString
It represents a character string whose internal structure will depend on its length. Let L the length of the string, then:
If 0 <L <255 then:

So no, CString is always 0 to 255 characters.

I don't know spanish but with google translate I can see (you just read the first condition you need to continue reading)
Quote
CString
Represents a character string whose internal structure depends on its
length
. Let L the length of the string, then:
If 0 <L <255 then:
Bytes      Data Type        Description
       1      Integer            length string.
n * (1)    Character         charcter.

If L = 0 then
Bytes     Data Type       Description
       1     Flag                Value: 0x00 to indicate that the string is empty.

If L> = 255 then:
Bytes       Data Type            Description
       1       Flag                     Value: 0xFF indicating that the chain is long.
       2       Integer                length string.
n * (1)     Character            Character.

Character and Flag
These types represent a byte; they are essentially the same. The only difference is
that contains a value that corresponds to an ASCII Character Code. In
change the value containing a Flag will be predefined.

so CString it self is record (or better a class);

Quote
Although I agree with you that this could be better done with classes it seems that's too complicated for GMP_47.
I guess but again I think this is a C/C++ assignment (originally), and he'll need to know classes OR pointers and dynamic memory allocation techniques plus be organized and know what/when todo to accomplish it in fashion way.

rvk

  • Hero Member
  • *****
  • Posts: 6684
Re: need help with create a file like this
« Reply #70 on: September 28, 2015, 02:06:00 am »
GMP_47, I already told you that there is a flou in the implementation, and that is assuming the length of the string will always be 0<length<255; but in the pdf file you attached is clearly stating that to handle the
data length = 0 or > 255; file structure should e altered slightly;
Woops...  %) sorry shobits1. I just now see the second page in that PDF.

Si L>=255 entonces
Flag = $FF followed by a Word (2 bytes) with the length of the string in case > 255 characters.

This could easily be implemented afterwards in the myReadString. In that case FieldText could be a normal string and the myReadString could just check for the $FF after which it can read the larger string.

@GMP_47. Before the final program is presented you need to take care of that.


Edit:
I guess but again I think this is a C/C++ assignment (originally), and he'll need to know classes OR pointers and dynamic memory allocation techniques plus be organized and know what/when todo to accomplish it in fashion way.
Yeah... but not with that old FPC 1.0.6.
In that case using a newer FPC or even Lazarus would be preferred.

I also saw the second half of the assignment... changing and adding records... That's gonna be a hoot  :P
« Last Edit: September 28, 2015, 02:10:19 am by rvk »

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with create a file like this
« Reply #71 on: September 28, 2015, 02:10:19 am »
Quote
I guess but again I think this is a C/C++ assignment (originally), and he'll need to know classes OR pointers and dynamic memory allocation techniques plus be organized and know what/when todo to accomplish it in fashion way.
I have to do this classic mode. I'll be taught OOP when this is over.

"eff it. do it in pascal :hauntingLaugh:"

shobits1

  • Sr. Member
  • ****
  • Posts: 271
  • .
Re: need help with create a file like this
« Reply #72 on: September 28, 2015, 02:11:58 am »
well, that a way out if you just planning to read the file but I already see the 2nd requirement of the task in hand; and it's
Quote
Crear, que el usuario podrá utilizar para generar un archivo de este
tipo con la información que él desee almacenar.
which with google says
Quote
Create, the user can use to generate a file of this
type the information that you want to store it.
and things will get messy when he starts doing the creating file task.

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with create a file like this
« Reply #73 on: September 28, 2015, 02:14:54 am »
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: ShortString;   //1 byte
  end;
  TRecordField = record
    Fieldnr: Word;  //2 bytes
    FieldText: String[255];  //1 byte
  end;

var
  BinaryStream: File;
  Header: THeader;                     //Header.Serial Filename Date Fieldnrs NrsRecords
  Fields: array [0..20] of TFields;    //Fields.Fieldnr     Fields.Fieldname
  Rec: array[0..20] of TRecordField;   //Rec.Fieldnr        Rec.FieldText
  Len: Byte;
  nrs: Integer;  //2 bytes
  I,N: Integer;

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

begin
  myRead(Len, 1);
  S[0] := Chr(Len);
  myRead(S[1], Len);
end;


begin
  assign(BinaryStream, 'C:\Dev-Pas\EXAMEN2.dat');
  reset(BinaryStream, 1);
  myReadWord(Header.Serial);
  myReadString(Header.Filename);

  myReadWord(Header.Date);
  myReadWord(Header.Fieldnrs);

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

       for N := 0 to Header.NrsRecords - 1 do
         begin
         myReadWord (Header.Fieldnrs);

                for I := 0 to Header.Fieldnrs - 1 do
                begin
                     myReadWord (Rec[I].Fieldnr);
                     myReadString (Rec[I].FieldText);
                     Writeln (Fields[I].Fieldname,': ',Rec[I].FieldText);
                end;
       end;
Writeln ('----[FIN CONTENIDO DEL ARCHIVO]-----------------');
Close(BinaryStream);
ReadLn;
end.
it's crashing

rvk

  • Hero Member
  • *****
  • Posts: 6684
Re: need help with create a file like this
« Reply #74 on: September 28, 2015, 02:16:50 am »
it's crashing
You still have the swap-lines in there.
I've already said (3 times)... remove them. The myReadWord does the swap for you.
You don't need it anymore in your main code.

 

TinyPortal © 2005-2018