* Newbie Question: Integer_IO an Data_error @ 2009-03-26 21:57 Zachary Kline 2009-03-26 22:18 ` Tim Rowe ` (2 more replies) 0 siblings, 3 replies; 9+ messages in thread From: Zachary Kline @ 2009-03-26 21:57 UTC (permalink / raw) Hi all, I'm quite new to the world of Ada, and currently trying to come to grips with it. I wrote for my own amusement a simple number-guessing game, which works mostly as I intended. The problem comes when handling exceptions. I can handle the case where a user typed a number too large or too small: that's a Constraint_Error, and I just prompt again and read another guess. The problem comes with Data_errors: if I try to handle that case the same way, we get a seemingly infinite loop. I'm using Gnat 4.24 on Slackware Linux, if that matters. Code for the procedure in question is below: procedure Get_Guess (Target : out Guess) is begin Put ("Your guess: "); Get(Target); 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); when others => raise; end Get_Guess; Any advice would be greatly appreciated. Best and thanks, Zack. -- Love: When you like to think of someone on days that begin with a morning. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Newbie Question: Integer_IO an Data_error 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 ` (2 more replies) 2009-03-27 5:15 ` anon 2009-03-27 8:54 ` Dmitry A. Kazakov 2 siblings, 3 replies; 9+ messages in thread From: Tim Rowe @ 2009-03-26 22:18 UTC (permalink / raw) 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'd try doing a string Get after a failed numeric get, to see what's still in the input stream. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Newbie Question: Integer_IO an Data_error 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 2009-03-27 8:59 ` Jean-Pierre Rosen 2 siblings, 1 reply; 9+ messages in thread From: Zachary Kline @ 2009-03-26 23:57 UTC (permalink / raw) This works, after a fashion. I suspec the problem does indeed have to do with the input stream. The solution of doing a string get seems needlessly hack-ish. That being said, I'm sure a simpler approach exists, though I can't find a function to flush the stream. Thanks much, Zack. -- Love: When you like to think of someone on days that begin with a morning. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Newbie Question: Integer_IO an Data_error 2009-03-26 23:57 ` Zachary Kline @ 2009-03-27 0:23 ` Tim Rowe 0 siblings, 0 replies; 9+ messages in thread From: Tim Rowe @ 2009-03-27 0:23 UTC (permalink / raw) Zachary Kline wrote: > This works, after a fashion. I suspec the problem does indeed have to > do with the input stream. The solution of doing a string get seems > needlessly hack-ish. The string Get was for diagnosis, not to leave in the final code! ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Newbie Question: Integer_IO an Data_error 2009-03-26 22:18 ` Tim Rowe 2009-03-26 23:57 ` Zachary Kline @ 2009-03-27 0:03 ` Adam Beneschan 2009-03-27 0:19 ` Zachary Kline 2009-03-27 8:59 ` Jean-Pierre Rosen 2 siblings, 1 reply; 9+ messages in thread From: Adam Beneschan @ 2009-03-27 0:03 UTC (permalink / raw) 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 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Newbie Question: Integer_IO an Data_error 2009-03-27 0:03 ` Adam Beneschan @ 2009-03-27 0:19 ` Zachary Kline 0 siblings, 0 replies; 9+ messages in thread From: Zachary Kline @ 2009-03-27 0:19 UTC (permalink / raw) Adam Beneschan <adam@irvine.com> writes: > 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. This does precisely what I was looking for. Thanks, Adam. The program now works as expected and intended. Hopefully Ada will continue to be as ellegant and expressive as it has so far. I like it. Thanks again, Zack. -- Love: When you like to think of someone on days that begin with a morning. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Newbie Question: Integer_IO an Data_error 2009-03-26 22:18 ` Tim Rowe 2009-03-26 23:57 ` Zachary Kline 2009-03-27 0:03 ` Adam Beneschan @ 2009-03-27 8:59 ` Jean-Pierre Rosen 2 siblings, 0 replies; 9+ messages in thread From: Jean-Pierre Rosen @ 2009-03-27 8:59 UTC (permalink / raw) Tim Rowe a �crit : > 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'd try doing a string Get after a > failed numeric get, to see what's still in the input stream. When a character is incorrect, the current position stays on it, to allow you to do a Get(Char) and see what happened. OTOH, it means that you must do a skip_line to get rid of the remaining of the line, and get a fresh one. A typical reading loop is: loop begin Get (N); exit; -- OK, no exception exception when Data_Error => Skip_Line; Put_Line ("Error, try again"); end; end loop; -- --------------------------------------------------------- J-P. Rosen (rosen@adalog.fr) Visit Adalog's web site at http://www.adalog.fr ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Newbie Question: Integer_IO an Data_error 2009-03-26 21:57 Newbie Question: Integer_IO an Data_error Zachary Kline 2009-03-26 22:18 ` Tim Rowe @ 2009-03-27 5:15 ` anon 2009-03-27 8:54 ` Dmitry A. Kazakov 2 siblings, 0 replies; 9+ messages in thread From: anon @ 2009-03-27 5:15 UTC (permalink / raw) You must use Skip_Line procedure and remove all Gets within the exception handlers! with Ada.Text_IO ; use Ada.Text_IO ; function test return integer is -- just for the fun of it type Guess is new Integer ; package I_IO is new Ada.Text_IO.Integer_IO ( Guess ) ; use I_IO ; procedure Get_Guess (Target : out Guess) is begin new_line ; Put ("Your guess: "); Get(Target); exception when Constraint_Error => Put_Line ("Please, numbers from one to a hundred only."); when Data_Error => Put_Line ("Numbers only, please."); when others => raise ; end Get_Guess; Temp : Guess := 0 ; begin loop begin Get_Guess ( Temp ) ; Put_Line ("Done"); exit when temp = 6 ; exception when others => Put_Line ("Bad Data"); return -7 ; end ; Skip_Line ; end loop ; return 0 ; exception when others => return -1 ; end test ; In <873ad0ueva.fsf@babel.localdomain>, Zachary Kline <kline.zachary@gmail.com> writes: >Hi all, >I'm quite new to the world of Ada, and currently trying to come to grips >with it. >I wrote for my own amusement a simple number-guessing game, which >works mostly as I intended. The problem comes when handling >exceptions. I can handle the case where a user typed a number too large >or too small: that's a Constraint_Error, and I just prompt again and >read another guess. The problem comes with Data_errors: if I try to >handle that case the same way, we get a seemingly infinite loop. >I'm using Gnat 4.24 on Slackware Linux, if that matters. >Code for the procedure in question is below: > procedure Get_Guess (Target : out Guess) is > begin > Put ("Your guess: "); > Get(Target); > 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); > when others => raise; > end Get_Guess; >Any advice would be greatly appreciated. >Best and thanks, >Zack. >-- >Love: >When you like to think of someone on days that begin with a morning. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Newbie Question: Integer_IO an Data_error 2009-03-26 21:57 Newbie Question: Integer_IO an Data_error Zachary Kline 2009-03-26 22:18 ` Tim Rowe 2009-03-27 5:15 ` anon @ 2009-03-27 8:54 ` Dmitry A. Kazakov 2 siblings, 0 replies; 9+ messages in thread From: Dmitry A. Kazakov @ 2009-03-27 8:54 UTC (permalink / raw) On Thu, 26 Mar 2009 14:57:13 -0700, Zachary Kline wrote: > I wrote for my own amusement a simple number-guessing game, which > works mostly as I intended. The problem comes when handling > exceptions. I can handle the case where a user typed a number too large > or too small: that's a Constraint_Error, and I just prompt again and > read another guess. The problem comes with Data_errors: if I try to > handle that case the same way, we get a seemingly infinite loop. A general advise is that when you read user input do not parse it as you read. That cannot work. Instead of that, read the whole line and then parse the string obtained, using Ada.Text_IO.Integer_IO (or something better): type Guess is new Integer; package Guess_IO is new Ada.Text_IO.Integer_IO (Guess); use Guess_IO; function Get_Guess return Guess is Result : Guess; begin loop Put ("Your guess:"); declare Line : constant String := Get_Line; Last : Positive; begin Get (Line, Result, Last); if Last = Line'Last then return Result; end if; Put_Line ("Unrecognized text after the number"); exception when Constraint_Error => Put_Line ("Out of range"); when Data_Error => Put_Line ("Not a number"); when End_Error => Put_Line ("Nothing found"); end; end loop; end Get_Guess; -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2009-03-27 8:59 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 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 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
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox