comp.lang.ada
 help / color / mirror / Atom feed
From: Adam Beneschan <adam@irvine.com>
Subject: Re: Newbie Question: Integer_IO an Data_error
Date: Thu, 26 Mar 2009 17:03:06 -0700 (PDT)
Date: 2009-03-26T17:03:06-07:00	[thread overview]
Message-ID: <13affeba-f5f5-43a5-a476-9d486b1c4517@z16g2000prd.googlegroups.com> (raw)
In-Reply-To: Wp6dnQTpg6rFYlbUnZ2dnUVZ8tudnZ2d@posted.plusnet

On Mar 26, 3:18 pm, Tim Rowe <spamt...@tgrowe.plus.net> wrote:
> Zachary Kline wrote:
> > The problem comes with Data_errors: if I try to
> > handle that case the same way, we get a seemingly infinite loop.
>
> I'm an Ada newbie too, but the first thing I wonder is what Get does
> with the input characters if they don't match the expected type. I
> wonder whether it leaves them on the input stream -- in which case
> subsequent attempts to read the input will try to read the same
> characters each time. Until somebody who knows what they're talking
> about comes along (won't be long)

I'm sure you're right, that it won't be long.  In the meantime, you're
stuck with me.

Anyway, A.10.8(8) says that Get (in Integer_IO), when Width=0, "reads
the longest possible sequence of characters matching the syntax of a
numeric literal without a point".  [I presume they mean "decimal
point" and aren't making any commentary about whether the number you
read will be useful or not.]  The way I interpret this, if the first
character in the input stream (past any leading blanks) is something
other than a digit or a sign, the longest possible sequence is zero
characters.  It's not 100% clear, since a zero-character sequence
doesn't match the syntax of a numeric literal either, but that's what
I think should happen.  So if it can't read any integer, it will leave
everything in the input stream (other than leading blanks).  I think
that if there's a sign followed by garbage, it will swallow up the
sign before raising Data_Error, though.

So this does result in an "infinite" loop, although that won't happen
the way the OP coded it:

         exception when Constraint_Error => Put_Line ("Please, numbers
from one to a hundred only.");
           Put ("Your guess: ");
           Get (Target);
           when Data_Error => Put_Line ("Numbers only, please.");
              Put ("Your guess: ");
              Get (Target);

The Get calls that appear in the exception handler are *not*
controlled by the exception handlers.  So if another Constraint_Error
or Data_Error occurs in those Get calls, it won't loop back and
execute the same exception handler, but will rather look for an
*outside* exception handler that catches the exceptions, or die if
there isn't one.  To write this properly, you'll need to write a loop,
perhaps

      Ch : Character;
   begin
      Input_Loop:
      loop
          begin
             Put ("Your guess: ");
             Get (Target);
             exit Input_Loop;
          exception
             when Constraint_Error =>
                Put_Line ("Please, numbers from one to a hundred
only");
             when Data_Error =>
                Put_Line ("Numbers only, please");
                Get (Ch);  -- or something else
          end;
      end loop Input_Loop;
   end Get_Guess;

 I'd try doing a string Get after a
> failed numeric get, to see what's still in the input stream.

Get(Ch) would eat the next character in the input stream if there's a
Data_Error; more likely, you'd want to say Skip_Line to throw away
everything in the rest of the line, but that depends on how you want
the program to work.

                               -- Adam



  parent reply	other threads:[~2009-03-27  0:03 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-26 21:57 Newbie Question: Integer_IO an Data_error Zachary Kline
2009-03-26 22:18 ` Tim Rowe
2009-03-26 23:57   ` Zachary Kline
2009-03-27  0:23     ` Tim Rowe
2009-03-27  0:03   ` Adam Beneschan [this message]
2009-03-27  0:19     ` Zachary Kline
2009-03-27  8:59   ` Jean-Pierre Rosen
2009-03-27  5:15 ` anon
2009-03-27  8:54 ` Dmitry A. Kazakov
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox