Sign in Join

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

Mailing lists / fpc-pascal / 2004-03

exception handling

12 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

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

kractor

spent a few moments going over the docs in the manual re: exception handling. for some reason it just doesn't seem to be sinking in, as nothing i've tried as of yet has managed to stop prog from crashing when data in input that's of a different type than program is expecting (string as opposed to integer, for example).

as i said, i'm pretty sure that its something really small and obvious, i'll include a few lines here ... maybe someone can spot my mistake ... pretty sure its the EConvertError and that there's a pre-defined error type that I just haven't come across yet.

        try
            readln(NewAlbum.Year);
        except
            on EConvertError do NewAlbum.Year := 0;
        end;

Reply by email

Thomas Schatzl
to kractor

Subject: [fpc-pascal]exception handling

Show quoted text 16 lines
spent a few moments going over the docs in the manual re: exception handling. for some reason it just doesn't seem to be sinking in, as nothing i've tried as of yet has managed to stop prog from crashing when data in input that's of a different type than program is expecting (string as opposed to integer, for example). as i said, i'm pretty sure that its something really small and obvious, i'll include a few lines here ... maybe someone can spot my mistake ... pretty sure its the EConvertError and that there's a pre-defined error type that I just haven't come across yet. try readln(NewAlbum.Year); except on EConvertError do NewAlbum.Year := 0; end;

- did you include the sysutils unit?
- afaik readln just raises runtime error which is unspecified according to the docs; eventually an EIOError (or similar if this does not exist) because this behaviour can be turned on/off with $I+/-.
But to be sure, you might want to catch general exceptions.
- do the following:

s: String;
i : Integer;
code : Word;
try
    readln(s);
    i := StrToInt(s);
catch
    on EIOError ...
end;

or

    {$I-}
    readln(i);
    {$I+}
    if (IOResult  0) then ... // IOResult (hopefully) contains an error
number in case of an I/O error

or

    readln(s);
    val(s, i, code);
    if (code  0) then Error...

But this has not been verified but it should be about right....

Regards,
Thomas

Reply by email

Thomas Schatzl
to Thomas Schatzl

Hi again,

Show quoted text 11 lines
> spent a few moments going over the docs in the manual re: exception > handling. for some reason it just doesn't seem to be sinking in, as > nothing i've tried as of yet has managed to stop prog from crashing when > data in input that's of a different type than program is expecting > (string as opposed to integer, for example). [...] - did you include the sysutils unit? - afaik readln just raises runtime error which is unspecified according to the docs; eventually an EIOError (or similar if this does not exist)

because

Show quoted text 14 lines
this behaviour can be turned on/off with $I+/-. But to be sure, you might want to catch general exceptions. - do the following: s: String; i : Integer; code : Word; try readln(s); i := StrToInt(s); catch on EIOError ... end;

Obviously it should mean "on EConvertError..." here because StrToInt raises an EConvertError when the string does not represent a valid integer.... (see docs)
Not an EIOError, this one probably slipped in because I was talking about catching an I/O Error in the other variants...

Sorry,
Thomas

Reply by email

kractor
to Thomas Schatzl
Thomas Schatzl wrote 54 lines
Hi again, >>spent a few moments going over the docs in the manual re: exception >>handling. for some reason it just doesn't seem to be sinking in, as >>nothing i've tried as of yet has managed to stop prog from crashing when >>data in input that's of a different type than program is expecting >>(string as opposed to integer, for example). >> >> >[...] > >- did you include the sysutils unit? >- afaik readln just raises runtime error which is unspecified according to >the docs; eventually an EIOError (or similar if this does not exist) > > because >this behaviour can be turned on/off with $I+/-. >But to be sure, you might want to catch general exceptions. >- do the following: > >s: String; >i : Integer; >code : Word; > >try > readln(s); > i := StrToInt(s); >catch > on EIOError ... >end; > > Obviously it should mean "on EConvertError..." here because StrToInt raises an EConvertError when the string does not represent a valid integer.... (see docs) Not an EIOError, this one probably slipped in because I was talking about catching an I/O Error in the other variants... Sorry, Thomas _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

thank you kindly, this worked perfectly. to be honest, the thought of reading the data initially as a string and then using a conversion to trap the error hadn't even crossed my mind ... :)

Reply by email

Michael Van Canneyt
to kractor: spent a few moments going over the docs in the manual re: exception handling. for some…
kractor wrote 16 lines
spent a few moments going over the docs in the manual re: exception handling. for some reason it just doesn't seem to be sinking in, as nothing i've tried as of yet has managed to stop prog from crashing when data in input that's of a different type than program is expecting (string as opposed to integer, for example). as i said, i'm pretty sure that its something really small and obvious, i'll include a few lines here ... maybe someone can spot my mistake ... pretty sure its the EConvertError and that there's a pre-defined error type that I just haven't come across yet. try readln(NewAlbum.Year); except on EConvertError do NewAlbum.Year := 0; end;

This should be:

      try
           readln(NewAlbum.Year);
      except
          on E : EConvertError do NewAlbum.Year := 0;
      end;

Michael.

Reply by email

kractor
to Michael Van Canneyt
Michael Van Canneyt wrote 40 lines
On Tue, 16 Mar 2004, kractor wrote: >spent a few moments going over the docs in the manual re: exception >handling. for some reason it just doesn't seem to be sinking in, as >nothing i've tried as of yet has managed to stop prog from crashing when >data in input that's of a different type than program is expecting >(string as opposed to integer, for example). > >as i said, i'm pretty sure that its something really small and obvious, >i'll include a few lines here ... maybe someone can spot my mistake ... >pretty sure its the EConvertError and that there's a pre-defined error >type that I just haven't come across yet. > > try > readln(NewAlbum.Year); > except > on EConvertError do NewAlbum.Year := 0; > end; > > This should be: try readln(NewAlbum.Year); except on E : EConvertError do NewAlbum.Year := 0; end; Michael. _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

tried your suggestion and when i attempted to input string when prog expecting integer value, it gave following error

An unhandled exception occurred at 0x004012CC :
EInOutError : Invalid input

so, i tried changing the EConvertError to EInOutError, little code paste follows

        try
            readln(NewAlbum.Year);
        except
            on E : EInOutError do NewAlbum.Year := 0;
        end;
        write('label: ');
        readln(NewAlbum.alLabel);
        write('tracks: ');
        readln(NewAlbum.NumTracks);

what's happening now is that when "invalid" data type is entered which triggers the exception handle, the program is "skipping" the readln(NewAlbum.alLabel) command and resuming apparently normal operations on the very next line [write('tracks: ');]. when valid data is entered, the program naturally doesn't trigger the exception handle and everything works normally.

Reply by email

Unknown author
Show quoted text 16 lines
> > try > readln(NewAlbum.Year); > except > on EConvertError do NewAlbum.Year := 0; > end; This should be: try readln(NewAlbum.Year); except on E : EConvertError do NewAlbum.Year := 0; end;

What are the costs of using exceptional handling ? Is the overhead similar to that incurred by C++ programs ?

cheers,
-Krish

Reply by email

Michael Van Canneyt
to kractor: tried your suggestion and when i attempted to input string when prog expecting integer…
kractor wrote 67 lines
Michael Van Canneyt wrote: >On Tue, 16 Mar 2004, kractor wrote: > > > >>spent a few moments going over the docs in the manual re: exception >>handling. for some reason it just doesn't seem to be sinking in, as >>nothing i've tried as of yet has managed to stop prog from crashing when >>data in input that's of a different type than program is expecting >>(string as opposed to integer, for example). >> >>as i said, i'm pretty sure that its something really small and obvious, >>i'll include a few lines here ... maybe someone can spot my mistake ... >>pretty sure its the EConvertError and that there's a pre-defined error >>type that I just haven't come across yet. >> >> try >> readln(NewAlbum.Year); >> except >> on EConvertError do NewAlbum.Year := 0; >> end; >> >> > >This should be: > > > try > readln(NewAlbum.Year); > except > on E : EConvertError do NewAlbum.Year := 0; > end; > >Michael. > >_______________________________________________ >fpc-pascal maillist - >http://lists.freepascal.org/mailman/listinfo/fpc-pascal > > > tried your suggestion and when i attempted to input string when prog expecting integer value, it gave following error An unhandled exception occurred at 0x004012CC : EInOutError : Invalid input so, i tried changing the EConvertError to EInOutError, little code paste follows try readln(NewAlbum.Year); except on E : EInOutError do NewAlbum.Year := 0; end; write('label: '); readln(NewAlbum.alLabel); write('tracks: '); readln(NewAlbum.NumTracks); what's happening now is that when "invalid" data type is entered which triggers the exception handle, the program is "skipping" the readln(NewAlbum.alLabel) command and resuming apparently normal operations on the very next line [write('tracks: ');]. when valid data is entered, the program naturally doesn't trigger the exception handle and everything works normally.

I have been able to reproduce this. However, I'm not sure what the cause it. My guess is that the end-of-line is not consumed before the exception is raised, and therefore the

        readln(NewAlbum.alLabel);

line gets an empty input line. Delphi does consume the end-of-line, and waits for the input of the label.

This is a very tricky issue, I think the core FPC list needs to discuss it.

For the moment, I would do like this;
Var
  A : String;
begin
         readln(A);
         NewAlbum.Year:=StrToIntDef(A,0);
         write('label: ');
         readln(NewAlbum.alLabel);
         write('tracks: ');
         readln(NewAlbum.NumTracks);

This avoids the exception.

Michael.

Reply by email

kractor
to Michael Van Canneyt
Michael Van Canneyt wrote 27 lines
I have been able to reproduce this. However, I'm not sure what the cause it. My guess is that the end-of-line is not consumed before the exception is raised, and therefore the readln(NewAlbum.alLabel); line gets an empty input line. Delphi does consume the end-of-line, and waits for the input of the label. This is a very tricky issue, I think the core FPC list needs to discuss it. For the moment, I would do like this; Var A : String; begin readln(A); NewAlbum.Year:=StrToIntDef(A,0); write('label: '); readln(NewAlbum.alLabel); write('tracks: '); readln(NewAlbum.NumTracks); This avoids the exception.

if there's anyting anyone needs from me on this, feel free to let me know. since you've indicated that you've been able to reproduce the error i'll assume you won't need the code that I have. however, should that be needed i'd be more than happy to send it.

Reply by email

kractor
to Michael Van Canneyt: I have been able to reproduce this. However, I'm not sure what the cause it. My guess is…
Michael Van Canneyt wrote 28 lines
I have been able to reproduce this. However, I'm not sure what the cause it. My guess is that the end-of-line is not consumed before the exception is raised, and therefore the readln(NewAlbum.alLabel); line gets an empty input line. Delphi does consume the end-of-line, and waits for the input of the label. This is a very tricky issue, I think the core FPC list needs to discuss it. For the moment, I would do like this; Var A : String; begin readln(A); NewAlbum.Year:=StrToIntDef(A,0); write('label: '); readln(NewAlbum.alLabel); write('tracks: '); readln(NewAlbum.NumTracks); This avoids the exception.

just wondering if there's been any progress on this? not trying to pressure or anything, more curious as to what the actual problem was if its been discovered yet ... also wondering if anyone else had this problem besides me?

Reply by email

Jonas Maebe
to kractor
kractor wrote 14 lines
> begin > readln(A); > NewAlbum.Year:=StrToIntDef(A,0); > write('label: '); > readln(NewAlbum.alLabel); > write('tracks: '); > readln(NewAlbum.NumTracks); > > This avoids the exception. > just wondering if there's been any progress on this? not trying to pressure or anything, more curious as to what the actual problem was if its been discovered yet ... also wondering if anyone else had this problem besides me?

The problem is simply that "readln" is split into "read" and "readline_end". The former reads whatever you want to read, the latter consumes the end-of-line. The ioresult is checked after both operations. If the read already returned an error, then an exception will be raised, so the readln_end is never executed.

That's the way readln (and writeln) was implemented from the start in FPC. I don't know if there's an elegant solution possible, or that it requires to change the whole way we handle it (e.g. passing a boolean to each internal read routine that notes whether or not it should consume everything till the end of the current line, no matter what happens).

Jonas

Reply by email

kractor
to Jonas Maebe
Jonas Maebe wrote 12 lines
The problem is simply that "readln" is split into "read" and "readline_end". The former reads whatever you want to read, the latter consumes the end-of-line. The ioresult is checked after both operations. If the read already returned an error, then an exception will be raised, so the readln_end is never executed. That's the way readln (and writeln) was implemented from the start in FPC. I don't know if there's an elegant solution possible, or that it requires to change the whole way we handle it (e.g. passing a boolean to each internal read routine that notes whether or not it should consume everything till the end of the current line, no matter what happens).

ok, thanks for clarifying that for me. it shouldn't be too difficult to find a workaround, in fact the code i'm using atm will do quite nicely since if its "triggered" the value is set to 0 and that's certainly something i can test for.

again, thanks ... :D

Reply by email