Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2011-12

more file operation problems

19 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Chris Kelling

I'm trying to assign the number of records to the rowCount of a stringgrid control. See the following code fragment:

var
   stock  : stockitem;
   rowNum : integer;
   {inventory is defined as a file of stockitem in another unit}
begin
   assignfile(inventory,'Ops');
   reset(inventory);
   stgInvOps.RowCount:= filesize(inventory);

When I compile the program, I get:

dashboard.pas(115,42) Error: Incompatible type for arg no. 1: Got "File
Of StockItem", expected "AnsiString" with 'inventory' highlighted
on the line "stgInvOps.RowCount:= filesize(inventory);"

What am I doing wrong?

-Chris

Reply by email

Henry Vermaak
to Chris Kelling
Chris Kelling wrote 20 lines
I'm trying to assign the number of records to the rowCount of a stringgrid control. See the following code fragment: var stock : stockitem; rowNum : integer; {inventory is defined as a file of stockitem in another unit} begin assignfile(inventory,'Ops'); reset(inventory); stgInvOps.RowCount:= filesize(inventory); When I compile the program, I get: dashboard.pas(115,42) Error: Incompatible type for arg no. 1: Got "File Of StockItem", expected "AnsiString" with 'inventory' highlighted on the line "stgInvOps.RowCount:= filesize(inventory);" What am I doing wrong?

It's using the wrong function, try System.FileSize?

Henry

Reply by email

Chris Kelling

-------- Begin forwarded message --------
Subject: Re: [Lazarus] more file operation problems Date: 12/12/11 2:35:32 PM
From: "Chris Kelling"
To:

Henry Vermaak wrote 15 lines
On 12/12/11 17:09, Chris Kelling wrote: > I'm trying to assign the number of records to the rowCount of a > stringgrid control. See the following code fragment: > > var > stock : stockitem; > rowNum : integer; > {inventory is defined as a file of stockitem in another unit} > > begin > assignfile(inventory,'Ops'); > reset(inventory); > stgInvOps.RowCount:= filesize(inventory); > It's using the wrong function, try System.FileSize?

That worked, but now, later in the code:

   rowNum := 1;
   while rowNum <= stgInvOps.RowCount do
         begin
           read(inventory,stock);
           stgInvOps.Cells[0,rowNum] := inttostr(stock.ClassNumber);
           inc(rowNum);
         end;
    closefile(inventory);

when I try to read from the file, in the IDE I get an exception:

Project Spares raised an exception class: 'External: SIGSEGV'

Running the exe outside the IDE, I get:
Access Violation

Press OK to ignore and risk data corruption.
Press Cancel to kill the program.

This is really getting frustrating.

-Chris

Reply by email

Sven Barth
to Chris Kelling
"Chris Kelling" wrote 11 lines
That worked, but now, later in the code: rowNum := 1; while rowNum <= stgInvOps.RowCount do begin read(inventory,stock); stgInvOps.Cells[0,rowNum] := inttostr(stock.ClassNumber); inc(rowNum); end; closefile(inventory);

Replace the "<=" condition by "<". The row indices go from 0 to RowCount-1.

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20111212/c02119eb/attachment.html>

Reply by email

Sven Barth
to Sven Barth
"Sven Barth" wrote 16 lines
Am 12.12.2011 21:05 schrieb "Chris Kelling" : > That worked, but now, later in the code: > > rowNum := 1; > while rowNum <= stgInvOps.RowCount do > begin > read(inventory,stock); > stgInvOps.Cells[0,rowNum] := inttostr(stock.ClassNumber); > inc(rowNum); > end; > closefile(inventory); > Replace the "<=" condition by "<". The row indices go from 0 to

RowCount-1.

And replace the "rowNum := 1" by "rowNum := 0" of course.

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20111212/c5d00a50/attachment.html>

Reply by email

Chris Kelling

On Mon, DEC 12, 2011 at 3:22 PM, Sven Bart wrote:

Am 12.12.2011 21:20 Schreiber "Sven Bart" <
<javascript:parent.wgMail.openComposeWindow(')>

Show quoted text 12 lines
: Am 12.12.2011 21:05 Schreiber "Chris Feeling" < <javascript:parent.wgMail.openComposeWindow(')> >: > That worked, but now, later in the code: > ?Rowan := 1; ?while Rowan <= stgInvOps.Row Count do ? ? ? ?begin ? ? > ? ? ?read(inventory,stock); ? ? ? ? ?stgInvOps.Cels[0,Rowan] := > into(stockcars); ? ? ? ? ?inc(Rowan); ? ? ? ?end; ? close > file(inventory); Replace the "<=" condition by "<". The row indices go from 0 to Row Count-1. And replace the "Rowan := 1" by "Rowan := 0" of course.

Row[0] is my header row and has fixed cells.

I do have more than one column, but I figured get one column working and adding the others will be the same. I do see a math error, though - I set the number of row to the number of records in the file, but I forgot to add in the header row, stgInvOps.RowCount needs to be one greater than the number of records.

That aside, I'm still having trouble getting the system to read from the file, and with the math error should get an out of range error not access denied or SIGSEGV. In fact, I replaced 'rowNum <= stgInvOps.count' with 'not eof(inventory)', and got the same error.

Thank you for your help thus far.
-Chris
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20111212/f11f8cfe/attachment.html>

Reply by email

Sergei Gorelkin
to Bart

15.12.2011 16:10, Bart ?????:

Show quoted text 8 lines
On 12/12/11, Chris Kelling wrote: As I posted in the other thread (http://lists.lazarus.freepascal.org/pipermail/lazarus/2011-December/069100.html) I think the problem is in the definition of your record type stockitem. It uses strings. Explicitely change that to ShortString.

Exactly so. Managed types cannot be used in typed files. This is rejected by Delphi, and by FPC > 2.4.4 as well. See http://bugs.freepascal.org/view.php?id=15447

Sergei

Reply by email

Chris Kelling
Sergei Gorelkin wrote 15 lines
15.12.2011 16:10, Bart ?????: > On 12/12/11, Chris Kelling wrote: > > As I posted in the other thread > > (http://lists.lazarus.freepascal.org/pipermail/lazarus/2011-December/069100.html) > I think the problem is in the definition of your record type > stockitem. > It uses strings. Explicitely change that to ShortString. > Exactly so. Managed types cannot be used in typed files. This is rejected by Delphi, and by FPC > 2.4.4 as well. See http://bugs.freepascal.org/view.php?id=15447 Sergei

It is confirmed - I forgot about ANSISTRING being a pointer type, and when I was writing the record out it wrote the address, not the data. Of course, when I read it back in, the address was not valid and this caused the error (derefrencing the non-existent pointer).

Thanks for helping me work through a stupid rookie mistake.

-Chris

Reply by email

Jürgen Hestermann
to Chris Kelling
It is confirmed - I forgot about ANSISTRING being a pointer type, and when I was writing the record out it wrote the address, not the data. Of course, when I read it back in, the address was not valid and this caused the error (derefrencing the non-existent pointer).

I often read that users don't need to bother about implementation details of certain things (strings or dynamic array types or ...). This clearly shows how important such informations are and that generic types are pitfalls.
You never realy know what you get.
If you would have used AnsiString instead of the generic String you would have got an error
and so would have been reminded that your assumptions (AnsiStrings) are not valid.

Reply by email

Bart
to Chris Kelling: It is confirmed - I forgot about ANSISTRING being a pointer type, and when I was writing…
Chris Kelling wrote
Thanks for helping me work through a stupid rookie mistake.

Did that once myself.
In a test program when I wrote and then read again all worked fine, only because the pointer was still valid.
When I examined the file, the filesize looked much smaller then I expected. Then SizeOf(MyRecordType) turned out to be not what I expected, and finally I got it.

Bart

Reply by email

Sven Barth
to Jürgen Hestermann: I often read that users don't need to bother about implementation details of certain…
J?rgen Hestermann wrote 17 lines
Chris Kelling schrieb: > It is confirmed - I forgot about ANSISTRING being a pointer type, and > when I was writing the record out it wrote the address, not the data. > Of course, when I read it back in, the address was not valid and this > caused the error (derefrencing the non-existent pointer). I often read that users don't need to bother about implementation details of certain things (strings or dynamic array types or ...). This clearly shows how important such informations are and that generic types are pitfalls. You never realy know what you get. If you would have used AnsiString instead of the generic String you would have got an error and so would have been reminded that your assumptions (AnsiStrings) are not valid.

With 2.6 and newer you'll also get an error if you use "String" and the record's unit is compiled in long string mode.

Regards,
Sven

Reply by email

Bart
to Sven Barth
Sven Barth wrote
With 2.6 and newer you'll also get an error if you use "String" and the record's unit is compiled in long string mode.

I hope you mean a warning, not an error.
It would break may of my existing progams.

Bart

Reply by email

Sven Barth
to Bart
Bart wrote 7 lines
On 12/16/11, Sven Barth wrote: > With 2.6 and newer you'll also get an error if you use "String" and the > record's unit is compiled in long string mode. I hope you mean a warning, not an error. It would break may of my existing progams.

The error appears only if you try to write(ln)/read(ln) such a record, because this simply can never work and is also a source of errors as this thread proves. The same error would appear if you'd have a record with a "AnsiString" (or "UnicodeString") field instead of the generic "String".

Regards,
Sven

Reply by email

Bart
to Sven Barth
Sven Barth wrote 5 lines
The error appears only if you try to write(ln)/read(ln) such a record, because this simply can never work and is also a source of errors as this thread proves. The same error would appear if you'd have a record with a "AnsiString" (or "UnicodeString") field instead of the generic "String".

For the sake of argument: if I wanted, willinlgy, to write such a record to (say) a logfile, for debugging purposes, the new fpc won't let me?
Is that Delphi compatible?

Bart

Reply by email

Sven Barth
to Bart
Bart wrote 12 lines
On 12/17/11, Sven Barth wrote: > The error appears only if you try to write(ln)/read(ln) such a record, > because this simply can never work and is also a source of errors as > this thread proves. The same error would appear if you'd have a record > with a "AnsiString" (or "UnicodeString") field instead of the generic > "String". For the sake of argument: if I wanted, willinlgy, to write such a record to (say) a logfile, for debugging purposes, the new fpc won't let me? Is that Delphi compatible?

I don't know whether it's Delphi compatible, but this error was already there if you've used AnsiString, so it is a logical extension that this error also appears if String is an alias to AnsiString.

And yes, the compiler won't let you write such a record (or let you even define a "file of" type of this record).

Regards,
Sven

Reply by email

Bart
to Sven Barth
Sven Barth wrote 6 lines
I don't know whether it's Delphi compatible, but this error was already there if you've used AnsiString, so it is a logical extension that this error also appears if String is an alias to AnsiString. And yes, the compiler won't let you write such a record (or let you even define a "file of" type of this record).

So, even if I am suicidal, the compiler will prevent me from shooting myself in the foot?
(Whereas C will shoot me in the foor even if I don't want to)

Although I like the fact that fpc prevents this (most likely) error in my coding, I still think the code itself is valid Pascal. It only does not do what I expect it to do.
So, I think a warning should suffice.

{$Mode Reductio_Ad_Absurdum}

If fpc forbids it, it should also forbid this:

var
  P: ^Integer;
begin
  p := nil;
  p^:= 1;
end.

This code is insane, but it is perfectly legal Pascal.

{$Mode Normal}

Feel free to differ and decide what you think is best. Most of the time when I disagree with some fpc devel, I (sometimes much) later come to the conclusion that I was "wrong" anyway.

Bart

Reply by email

Sven Barth
to Bart
"Bart" wrote 13 lines
On 12/17/11, Sven Barth wrote: > I don't know whether it's Delphi compatible, but this error was already > there if you've used AnsiString, so it is a logical extension that this > error also appears if String is an alias to AnsiString. > > And yes, the compiler won't let you write such a record (or let you even > define a "file of" type of this record). So, even if I am suicidal, the compiler will prevent me from shooting myself in the foot? (Whereas C will shoot me in the foor even if I don't want to)

That's the usual answer in this context: Pascal won't let you shoot yourself in the foot. :D

Although I like the fact that fpc prevents this (most likely) error in my coding, I still think the code itself is valid Pascal. It only does not do what I expect it to do. So, I think a warning should suffice.

It is valid Pascal as long as the types used aren't managed ones like dynamic arrays, ansistrings and widestrings. But as soon as you use such a type it isn't valid anymore in the context of file I/O. "String" is a hybrid here, because depending on a compiler option it can be legal Pascal or not.

Show quoted text 13 lines
{$Mode Reductio_Ad_Absurdum} If fpc forbids it, it should also forbid this: var P: ^Integer; begin p := nil; p^:= 1; end. This code is insane, but it is perfectly legal Pascal.

This is a different situation. Here the compiler would need to track the contents of variables when compiling (which is possible in theory - I'm hearing a lecture about this in the current term), while in the file case it's just simple type checking which the compiler does anyway.

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20111217/a9c0ef2b/attachment.html>

Reply by email

Bart
to Sven Barth
Sven Barth wrote 5 lines
It is valid Pascal as long as the types used aren't managed ones like dynamic arrays, ansistrings and widestrings. But as soon as you use such a type it isn't valid anymore in the context of file I/O. "String" is a hybrid here, because depending on a compiler option it can be legal Pascal or not.

[snip]

... while in the file case it's just simple type checking which the compiler does anyway.

Thanks for the explanation and your time.

Bart

Reply by email