* Re: Newbie question on Ada TExt_IO
2002-10-03 18:20 Newbie question on Ada TExt_IO Justin
@ 2002-10-03 18:50 ` Matthew Heaney
2002-10-03 19:05 ` Jeffrey Carter
` (5 subsequent siblings)
6 siblings, 0 replies; 27+ messages in thread
From: Matthew Heaney @ 2002-10-03 18:50 UTC (permalink / raw)
"Justin" <jbirtwell@yahoo.com> wrote in message
news:93d4dcd4.0210031020.b0cca2b@posting.google.com...
>
> I'm doing TextIO from the command prompt. But I'm having difficulty
> validating the input. For example I'm asking the user to enter a
> number, let's say I'm expecting an integer between 1 and 6
I recommend that you do *not* use Get to consume the value. Instead, use
Get_Line to consume the entire line, and then either use Integer'Value to
convert the text to an integer, or use the version of Get that reads from a
string buffer.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Newbie question on Ada TExt_IO
2002-10-03 18:20 Newbie question on Ada TExt_IO Justin
2002-10-03 18:50 ` Matthew Heaney
@ 2002-10-03 19:05 ` Jeffrey Carter
2002-10-03 19:35 ` David C. Hoos
` (4 subsequent siblings)
6 siblings, 0 replies; 27+ messages in thread
From: Jeffrey Carter @ 2002-10-03 19:05 UTC (permalink / raw)
Justin wrote:
> I'm doing TextIO from the command prompt. But I'm having difficulty
> validating the input. For example I'm asking the user to enter a
> number, let's say I'm expecting an integer between 1 and 6
>
> X:Integer;
> ...
> Put("Please enter a number between 1 and 6);
> Get(x);
>
> But what if they give me 'abc' or 4.44 or simply
> 1230000000000000000000000000000000000000000000000000000000000000000000000
>
> How can I handle this? From my take on what I've read I should avoid
> exception handling for things I'm not expecting, so I've ruled out
> exceptions, that leaves me with obtaining a value of generic type and
> evalutating the type at run-time...how can I do this? Is this the
> right strategy?
The first rule when doing interactive input is to always read an entire
line using Ada.Text_IO.Get_Line or a function that returns String such
as PragmARC.Get_Line. Then extract the value using 'Value or one of the
Get subprograms in Ada.Text_IO[.Integer_IO | .Float_IO | ...] that take
a String parameter. There are a number of subtle errors frequently
encountered with Text_IO that this avoids.
I think you misunderstood what you read about using exceptions. You
should avoid exceptions for things you ARE expecting. Using them for
exceptional circumstances is what they're for. In this case, you're
pretty much forced to do exception handling, unless you plan to
duplicate the parsing that already exists in 'Value and Ada.Text_IO.
The ARM is not very easy to read. The exceptions are Annex A, which
defines the standard library, and Annex K, which defines the standard
attributes. Everyone should be familiar with those.
The PragmAda Reusable Components are available from
http://home.earthlink.net/~jrcarter010/pragmarc.htm
--
Jeff Carter
"I blow my nose on you."
Monty Python & the Holy Grail
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Newbie question on Ada TExt_IO
2002-10-03 18:20 Newbie question on Ada TExt_IO Justin
2002-10-03 18:50 ` Matthew Heaney
2002-10-03 19:05 ` Jeffrey Carter
@ 2002-10-03 19:35 ` David C. Hoos
2002-10-03 19:35 ` tmoran
` (3 subsequent siblings)
6 siblings, 0 replies; 27+ messages in thread
From: David C. Hoos @ 2002-10-03 19:35 UTC (permalink / raw)
----- Original Message -----
From: "Justin" <jbirtwell@yahoo.com>
Newsgroups: comp.lang.ada
To: <comp.lang.ada@ada.eu.org>
Sent: Thursday, October 03, 2002 1:20 PM
Subject: Newbie question on Ada TExt_IO
> Hi,
>
> I'm relatively new to Ada. I've read 1/2 of Programming in Ada95 by
> Barnes, done half of Lovelace and read as much as I can stomach of the
> Ada RM. Forgive me if this question is too basic, but I've been unable
> to see any reference to it in the previous documentation.
>
> I'm doing TextIO from the command prompt. But I'm having difficulty
> validating the input. For example I'm asking the user to enter a
> number, let's say I'm expecting an integer between 1 and 6
>
> X:Integer;
> ...
> Put("Please enter a number between 1 and 6);
> Get(x);
>
> But what if they give me 'abc' or 4.44 or simply
> 1230000000000000000000000000000000000000000000000000000000000000000000000
>
First, I would be sure that the user prompt is precise in defining the
desired input. 4.44 _is_ "number between 1 and 6". If what you meant
is "Please enter an integer from 1 to 6 inclusive", I would say just that.
> How can I handle this? From my take on what I've read I should avoid
> exception handling for things I'm not expecting, so I've ruled out
> exceptions, that leaves me with obtaining a value of generic type and
> evalutating the type at run-time...how can I do this? Is this the
> right strategy?
I have seen some discussion deprecating the use of exception handlers for
validating user input, but frankly, I've never been convinced, and I use
them.
>
> Thanks for they help,
> Justin
> _______________________________________________
> comp.lang.ada mailing list
> comp.lang.ada@ada.eu.org
> http://ada.eu.org/mailman/listinfo/comp.lang.ada
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Newbie question on Ada TExt_IO
2002-10-03 18:20 Newbie question on Ada TExt_IO Justin
` (2 preceding siblings ...)
2002-10-03 19:35 ` David C. Hoos
@ 2002-10-03 19:35 ` tmoran
2002-10-03 19:43 ` Preben Randhol
` (2 subsequent siblings)
6 siblings, 0 replies; 27+ messages in thread
From: tmoran @ 2002-10-03 19:35 UTC (permalink / raw)
> Put("Please enter a number between 1 and 6);
> Get(x);
>
> But what if they give me 'abc' or 4.44 or simply
> 1230000000000000000000000000000000000000000000000000000000000000000000000
To be really snazzy, use Get_Line and read into a String, then check the
string to make sure it consists of the desired kind of input - in this
case a single digit in '1' .. '6' and perhaps spaces. If it's OK,
then Get from the string, if not tell the user just what he did wrong.
Substantially simpler is to catch the exception and go back and
repeat the Put prompt and the Get. Use exceptions judiciously, not
just for really totally surprising situations.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Newbie question on Ada TExt_IO
2002-10-03 18:20 Newbie question on Ada TExt_IO Justin
` (3 preceding siblings ...)
2002-10-03 19:35 ` tmoran
@ 2002-10-03 19:43 ` Preben Randhol
2002-10-03 19:55 ` Matthew Heaney
2002-10-04 2:42 ` SteveD
2002-10-04 17:34 ` Justin Birtwell
6 siblings, 1 reply; 27+ messages in thread
From: Preben Randhol @ 2002-10-03 19:43 UTC (permalink / raw)
On 3 Oct 2002 11:20:24 -0700, Justin wrote:
> How can I handle this? From my take on what I've read I should avoid
> exception handling for things I'm not expecting, so I've ruled out
> exceptions, that leaves me with obtaining a value of generic type and
> evalutating the type at run-time...how can I do this? Is this the
> right strategy?
No I would have used exceptions here. I find it difficult to see how you
can avoid it.
I recommend that you look at http://www.it.bton.ac.uk/staff/je/adacraft/ because
it has a lot of nice examples to start with.
Here is my implementation:
---------------------------------------------------------------
with Ada.Text_IO; use Ada.Text_IO;
procedure Feedback
is
Input : String(1..80);
Last : Integer;
begin
-- This example will loop until you give a correct number
loop
Put ("Please enter a number between 1 and 6 : ");
Get_Line (Item => Input, Last => Last);
-- I now choose a block because then I can
-- put a exception handler inside so that you will
-- be asked for a number until you give a correct
-- number
declare
-- Making a type that is from 1 to 6. If the character
-- you convert isn't in the range 1..6 then Constraint_Error
-- will be raised and we can handle it.
type Input_Number_Type is range 1..6;
Number : Input_Number_Type;
begin
-- we convert Input (1..1) to our Input_Number_Type
Number := Input_Number_Type'Value (Input (1..1));
Put_Line ("Thank you!");
-- OK conversion went well. (If it hadn't the program would
-- jump to exception below before instead of continuing)
exit;
-- Jumping out of the loop.
exception
when Constraint_Error =>
Put_Line ("Wrong number!");
end;
end loop;
end Feedback;
Preben
--
Ada95 is good for you.
http://libre.act-europe.fr/Software_Matters/02-C_pitfalls.pdf
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Newbie question on Ada TExt_IO
2002-10-03 19:43 ` Preben Randhol
@ 2002-10-03 19:55 ` Matthew Heaney
2002-10-03 20:07 ` Preben Randhol
0 siblings, 1 reply; 27+ messages in thread
From: Matthew Heaney @ 2002-10-03 19:55 UTC (permalink / raw)
"Preben Randhol" <randhol+news@pvv.org> wrote in message
news:slrnapp7f6.45u.randhol+news@kiuk0156.chembio.ntnu.no...
>
> No I would have used exceptions here. I find it difficult to see how you
> can avoid it.
The issue is that if there's an error, the bad input doesn't get consumed.
You have to remember to call Skip_Line, so you might as well call Get_Line
instead.
The other benefit is that you can interpret the input as meta-symbols. For
example, I often interrogate the input as a string first:
"quit"
"q"
"exit"
"x"
"first"
"last"
and if none of these test true, then I go ahead an interpret it as an
integer input.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Newbie question on Ada TExt_IO
2002-10-03 19:55 ` Matthew Heaney
@ 2002-10-03 20:07 ` Preben Randhol
0 siblings, 0 replies; 27+ messages in thread
From: Preben Randhol @ 2002-10-03 20:07 UTC (permalink / raw)
On Thu, 3 Oct 2002 15:55:08 -0400, Matthew Heaney wrote:
>
> "Preben Randhol" <randhol+news@pvv.org> wrote in message
> news:slrnapp7f6.45u.randhol+news@kiuk0156.chembio.ntnu.no...
>>
>> No I would have used exceptions here. I find it difficult to see how you
>> can avoid it.
>
> The issue is that if there's an error, the bad input doesn't get consumed.
> You have to remember to call Skip_Line, so you might as well call Get_Line
> instead.
I don't understand, I did use Get_Line in my code. I can see a couple of
problems though. I defined the String from only 1 to 80 so if you input
a string above 80 characters it will be split. I also should have
checked if the Last > 1 because one could give 1000 and the program
would accept it as 1, but I left this for the reader :-)
I wasn't refering to Get I was saying that I would use exceptions and I
have a bit problems with seeing a solution where you do not have any
exception handling when you expect user input.
Or in other words if you are dealing with a human then expect exceptions
;-)
--
Ada95 is good for you.
http://libre.act-europe.fr/Software_Matters/02-C_pitfalls.pdf
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Newbie question on Ada TExt_IO
2002-10-03 18:20 Newbie question on Ada TExt_IO Justin
` (4 preceding siblings ...)
2002-10-03 19:43 ` Preben Randhol
@ 2002-10-04 2:42 ` SteveD
2002-10-04 17:49 ` Justin Birtwell
2002-10-04 17:34 ` Justin Birtwell
6 siblings, 1 reply; 27+ messages in thread
From: SteveD @ 2002-10-04 2:42 UTC (permalink / raw)
"Justin" <jbirtwell@yahoo.com> wrote in message
news:93d4dcd4.0210031020.b0cca2b@posting.google.com...
> Hi,
[snip]
>
> X:Integer;
> ...
> Put("Please enter a number between 1 and 6);
> Get(x);
>
> But what if they give me 'abc' or 4.44 or simply
> 1230000000000000000000000000000000000000000000000000000000000000000000000
>
> How can I handle this? From my take on what I've read I should avoid
> exception handling for things I'm not expecting, so I've ruled out
> exceptions, that leaves me with obtaining a value of generic type and
> evalutating the type at run-time...how can I do this? Is this the
> right strategy?
I suggest that you handle this differently depending on the target audience
(or "user" if you prefer).
If I am putting together a small program for internal use, I typically use a
small loop with an exception handler... something along the lines of (pseudo
code):
loop
begin
Prompt for input
Get input
Exit when input is valid
exception
when others =>
Display a nastygram about invalid input
end;
end loop;
skip to the next line of input
If I am putting something together for external use, I would read the value
into a string using something like Text_Io.Read_Line with the string
ridicuously large (maybe 1..256). If after reading the string the value of
"last" is the size of the string, I know something is wrong and report an
error (unlikely to happen, but handled). Once I get a reasonably sized
string, I trim leading and trailing spaces using Ada.Fixed.Trim. Then I
check for valid characters using something like Ada.Strings.Fixed.Index to
make sure the numeric input contains only digits. Then I use the
Integer'Value to get the actual value of the numeric string. Just to be
safe the Integer'Value conversion is protected by an exception handler.
These days most programs for external use are GUI's, which change the rules
a bit but still require validation.
I hope this helps,
SteveD
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Newbie question on Ada TExt_IO
2002-10-04 2:42 ` SteveD
@ 2002-10-04 17:49 ` Justin Birtwell
2002-10-04 18:00 ` David C. Hoos
` (2 more replies)
0 siblings, 3 replies; 27+ messages in thread
From: Justin Birtwell @ 2002-10-04 17:49 UTC (permalink / raw)
Steve,
<<, I would read the value
into a string using something like Text_Io.Read_Line with the string
ridiculously large (maybe 1..256). >>
I couldn't find the package Text_IO.Read_Line did you mean Get_Line?
What 's the difference between having a huge array like String(1..256) and
using an Unbounded_String? Is it because we need the type to be
specifically String and not Unbounded_String? Couldn't we convert from one
to the other?
<< If after reading the string the value of
"last" is the size of the string, I know something is wrong and report an
error (unlikely to happen, but handled). Once I get a reasonably sized
string, I trim leading and trailing spaces using Ada.Fixed.Trim. >>
How do you evaluate the length of the string using "Input'Last" isn't always
going to be 256, it was for me?
<<Then I check for valid characters using something like
Ada.Strings.Fixed.Index to
make sure the numeric input contains only digits. Then I use the
Integer'Value to get the actual value of the numeric string. Just to be
safe the Integer'Value conversion is protected by an exception handler.>>
The Index function has a pattern matching parameter, how do you express "all
digits" without having to specify them individually?
Thanks for your help,
Justin
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Newbie question on Ada TExt_IO
2002-10-04 17:49 ` Justin Birtwell
@ 2002-10-04 18:00 ` David C. Hoos
2002-10-04 18:04 ` Preben Randhol
2002-10-04 18:00 ` Preben Randhol
2002-10-04 18:34 ` tmoran
2 siblings, 1 reply; 27+ messages in thread
From: David C. Hoos @ 2002-10-04 18:00 UTC (permalink / raw)
You might find some useful ideas for simpler ways to accomplish
this in my "toy" application found at ftp.ada95.com/pub/pet_store.zip
For example, the pet_store-price.adb file shows how to use the
'Value attribute to do all of that work for you -- i.e., "trimming"
the leading and trailing blanks, etc.
Another consideration is that in general to find the length of the
input string one should use something like Last - Input'First + 1;
----- Original Message -----
From: "Justin Birtwell" <jbirtwell@yahoo.com>
Newsgroups: comp.lang.ada
To: <comp.lang.ada@ada.eu.org>
Sent: Friday, October 04, 2002 12:49 PM
Subject: Re: Newbie question on Ada TExt_IO
> Steve,
>
> <<, I would read the value
> into a string using something like Text_Io.Read_Line with the string
> ridiculously large (maybe 1..256). >>
> I couldn't find the package Text_IO.Read_Line did you mean Get_Line?
>
> What 's the difference between having a huge array like String(1..256) and
> using an Unbounded_String? Is it because we need the type to be
> specifically String and not Unbounded_String? Couldn't we convert from
one
> to the other?
>
> << If after reading the string the value of
> "last" is the size of the string, I know something is wrong and report an
> error (unlikely to happen, but handled). Once I get a reasonably sized
> string, I trim leading and trailing spaces using Ada.Fixed.Trim. >>
>
> How do you evaluate the length of the string using "Input'Last" isn't
always
> going to be 256, it was for me?
>
> <<Then I check for valid characters using something like
> Ada.Strings.Fixed.Index to
> make sure the numeric input contains only digits. Then I use the
> Integer'Value to get the actual value of the numeric string. Just to be
> safe the Integer'Value conversion is protected by an exception handler.>>
>
> The Index function has a pattern matching parameter, how do you express
"all
> digits" without having to specify them individually?
>
> Thanks for your help,
> Justin
>
>
> _______________________________________________
> comp.lang.ada mailing list
> comp.lang.ada@ada.eu.org
> http://ada.eu.org/mailman/listinfo/comp.lang.ada
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Newbie question on Ada TExt_IO
2002-10-04 17:49 ` Justin Birtwell
2002-10-04 18:00 ` David C. Hoos
@ 2002-10-04 18:00 ` Preben Randhol
2002-10-04 18:02 ` Preben Randhol
2002-10-04 18:34 ` tmoran
2 siblings, 1 reply; 27+ messages in thread
From: Preben Randhol @ 2002-10-04 18:00 UTC (permalink / raw)
On Fri, 04 Oct 2002 17:49:26 GMT, Justin Birtwell wrote:
> Steve,
>
><<, I would read the value
> into a string using something like Text_Io.Read_Line with the string
> ridiculously large (maybe 1..256). >>
> I couldn't find the package Text_IO.Read_Line did you mean Get_Line?
I think he meant to define a Read_Line like below (I called it
Get_Whole_Line)
procedure Get_Whole_Line
(File : in File_Type;
Item : out String;
Last : out Natural)
is
begin
Get_Line (File => File, Item => Item, Last => Last);
if Last = Item'Last then
-- The line was longer than allowed, skipping the rest.
-- Can also raise an exception if necessary.
Skip_Line (File => File);
else
Fixed.Delete (Source => Item, From => Last + 1, Through => Item'Last);
end if;
Line_Number := Line_Number + 1;
end Get_Whole_Line;
--
Ada95 is good for you.
http://libre.act-europe.fr/Software_Matters/02-C_pitfalls.pdf
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Newbie question on Ada TExt_IO
2002-10-04 18:00 ` Preben Randhol
@ 2002-10-04 18:02 ` Preben Randhol
0 siblings, 0 replies; 27+ messages in thread
From: Preben Randhol @ 2002-10-04 18:02 UTC (permalink / raw)
On Fri, 4 Oct 2002 18:00:42 +0000 (UTC), Preben Randhol wrote:
> On Fri, 04 Oct 2002 17:49:26 GMT, Justin Birtwell wrote:
>> Steve,
>>
>><<, I would read the value
>> into a string using something like Text_Io.Read_Line with the string
>> ridiculously large (maybe 1..256). >>
>> I couldn't find the package Text_IO.Read_Line did you mean Get_Line?
>
> I think he meant to define a Read_Line like below (I called it
> Get_Whole_Line)
>
> procedure Get_Whole_Line
> (File : in File_Type;
> Item : out String;
> Last : out Natural)
> is
> begin
> Get_Line (File => File, Item => Item, Last => Last);
> if Last = Item'Last then
> -- The line was longer than allowed, skipping the rest.
> -- Can also raise an exception if necessary.
> Skip_Line (File => File);
> else
> Fixed.Delete (Source => Item, From => Last + 1, Through => Item'Last);
> end if;
>
> Line_Number := Line_Number + 1;
> end Get_Whole_Line;
Note I use my procedure to read from a file so you can remove the File
part if you are reading from stdin.
--
Ada95 is good for you.
http://libre.act-europe.fr/Software_Matters/02-C_pitfalls.pdf
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Newbie question on Ada TExt_IO
2002-10-04 17:49 ` Justin Birtwell
2002-10-04 18:00 ` David C. Hoos
2002-10-04 18:00 ` Preben Randhol
@ 2002-10-04 18:34 ` tmoran
2 siblings, 0 replies; 27+ messages in thread
From: tmoran @ 2002-10-04 18:34 UTC (permalink / raw)
> "last" is the size of the string,
This is true only if Input'first is 1. ie, if you had
Input : String(15 .. 237);
and the user entered 2 characters, Last = 16 and Input(15 .. 16), or
Input(Input'first .. Last), contains the two characters. It's not a good
habit to assume the first subscript is 1 and Last is the length. Often a
String has been passed to you as a parameter to a procedure, and the
caller may have passed just a portion of some bigger string, say
Input : String(1 .. 1024);
...
Input(1 .. 14) := "abcdefghijklmn";
Some_Procedure(Input(15 .. 237));
Some_Procedure will fail if it assumes its input parameter'first = 1.
>How do you evaluate the length of the string using "Input'Last" isn't always
>going to be 256, it was for me?
Input'last is the last legal subscript in Input. Given
Input : String(1 .. 256);
Input'last = 256. Permanently. Regardless of the content of Input.
Last is a variable set by Get_Line that tells the last subscript
Get_Line used to store an input character. If the user entered no
characters then Get_Line sets Last = Input'first-1 (zero in your
example). If he entered four characters "5432", then hit the Enter key,
then the '2' goes into Input(4) and Last = 4.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Newbie question on Ada TExt_IO
2002-10-03 18:20 Newbie question on Ada TExt_IO Justin
` (5 preceding siblings ...)
2002-10-04 2:42 ` SteveD
@ 2002-10-04 17:34 ` Justin Birtwell
2002-10-04 17:58 ` Preben Randhol
` (3 more replies)
6 siblings, 4 replies; 27+ messages in thread
From: Justin Birtwell @ 2002-10-04 17:34 UTC (permalink / raw)
Hello All,
To everyone that replied to my question..thank you. Through your responses
I learned allot. I learned how I could raise an error with in a loop by
nesting a block, I also learned about Skip_Line and Get_Line, the
Ada.Strings.Trim and the Ada.Strings.Fixed.Index packages. After reading
everyone's post I"ve decided that the best course of action is to validate
the input as much as I possibly can but still supply some exception handling
for anything that I haven't anticipated. So my validation looks like this
Accept entire line using Get_Line into string(1..256);
Check if first character is a digit
Check if digit is between 1 and 6
error handling
Here's the code:
with Text_Io;use Text_Io;
with StringFunctions;use StringFunctions;
procedure Test_IO_2 is
Input: String(1..256);
N:Integer;
Success:Boolean:=false;
Last:Integer;
begin
while success /=true loop
Put("PLease enter a number between 1 and 6");
Get_Line(Item=>Input,Last=>Last);
if Is_Digit(Input(1..1)) then
N:=Integer'Value(Input(1..1));
if N>=1 and N<=6 then
Success:=True;
end if;
else
success:=false;
Put_Line("Invalid entry, try again.");
end if;
end loop;
Put_Line("Thank you");
exception
when others=>
Put_Line("Error, Invalid data.");
end;
Is_Digit a hack of a procedure that compares the 1 character string to all
10 digits characters. I really have a lot to learn. What's giving me the
hardest time is working within the confines of strict/strong typing. The
Ada.Characters.Handling package already has an Is_Digit function, but it's
expecting a character not a single item String array! How can I convert
from one into the other? I have the distinct feelling like I'm reinventing
the wheel. Aren't packages aready made to do alot of this
converting/validation? If so where are they? How can one access them?
Does the RM list all the packages provided by Ada or are there more to be
discovered?
thanks to one and all,
Justin
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Newbie question on Ada TExt_IO
2002-10-04 17:34 ` Justin Birtwell
@ 2002-10-04 17:58 ` Preben Randhol
2002-10-04 18:13 ` tmoran
` (2 subsequent siblings)
3 siblings, 0 replies; 27+ messages in thread
From: Preben Randhol @ 2002-10-04 17:58 UTC (permalink / raw)
On Fri, 04 Oct 2002 17:34:42 GMT, Justin Birtwell wrote:
>
> Here's the code:
>
> with Text_Io;use Text_Io;
> with StringFunctions;use StringFunctions;
>
> procedure Test_IO_2 is
> Input: String(1..256);
> N:Integer;
> Success:Boolean:=false;
> Last:Integer;
> begin
> while success /=true loop
> Put("PLease enter a number between 1 and 6");
> Get_Line(Item=>Input,Last=>Last);
> if Is_Digit(Input(1..1)) then
> N:=Integer'Value(Input(1..1));
> if N>=1 and N<=6 then
> Success:=True;
> end if;
> else
> success:=false;
> Put_Line("Invalid entry, try again.");
> end if;
> end loop;
> Put_Line("Thank you");
> exception
> when others=>
> Put_Line("Error, Invalid data.");
> end;
OK but note that your program will not ask you again if you press
something other than a integer value.
>
> Is_Digit a hack of a procedure that compares the 1 character string to all
> 10 digits characters. I really have a lot to learn. What's giving me the
> hardest time is working within the confines of strict/strong typing. The
Well you will learn that this is a great benifit. In the beginning it
can be a bit annoying, but you will soon be diseplined enough to avoid
all these problems and you will fully see why strong typing is the only
way to go.
Preben
--
Ada95 is good for you.
http://libre.act-europe.fr/Software_Matters/02-C_pitfalls.pdf
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Newbie question on Ada TExt_IO
2002-10-04 17:34 ` Justin Birtwell
2002-10-04 17:58 ` Preben Randhol
@ 2002-10-04 18:13 ` tmoran
2002-10-04 20:07 ` Jeffrey Carter
2002-10-05 2:43 ` SteveD
3 siblings, 0 replies; 27+ messages in thread
From: tmoran @ 2002-10-04 18:13 UTC (permalink / raw)
>expecting a character not a single item String array! How can I convert
>from one into the other?
A String is an array of Character so you just subscript to get a
single value. String(1 .. 2) is a 2 character string, String(1 .. 1)
is a 1 character long string, and String(1) is a single Character.
So replace
> if Is_Digit(Input(1..1)) then
which is illegal, by
if Is_Digit(Input(1)) then
or, more simply,
if Input(1) in '0' .. '9' then
Note that there's a bug in your code: what happens if the user just
hits the Enter key without having typed in any characters for Input?
You might consider dropping the Success flag and instead using an
"exit" statement.
>Does the RM list all the packages provided by Ada or are there more to be
>discovered?
Particular compiler vendors usually supply extra stuff, and you can find
things at www.adaic.org or www.adapower.com, but yes, the RM lists all
the *official* Ada packages.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Newbie question on Ada TExt_IO
2002-10-04 17:34 ` Justin Birtwell
2002-10-04 17:58 ` Preben Randhol
2002-10-04 18:13 ` tmoran
@ 2002-10-04 20:07 ` Jeffrey Carter
2002-10-07 8:26 ` Fraser Wilson
2002-10-05 2:43 ` SteveD
3 siblings, 1 reply; 27+ messages in thread
From: Jeffrey Carter @ 2002-10-04 20:07 UTC (permalink / raw)
Justin Birtwell wrote:
> Accept entire line using Get_Line into string(1..256);
> Check if first character is a digit
> Check if digit is between 1 and 6
> error handling
>
> Here's the code:
>
> with Text_Io;use Text_Io;
> with StringFunctions;use StringFunctions;
>
> procedure Test_IO_2 is
> Input: String(1..256);
> N:Integer;
> Success:Boolean:=false;
> Last:Integer;
> begin
> while success /=true loop
Constructs like this frequently indicate a lack of understanding of what
a Boolean value is. This could be
while not Success loop
That's kind of hard to understand when you go around the loop and when
you stop. It's easier to understand if written
loop
exit when Success;
However, Success is an unnecessary flag. It would be better to eliminate
it, as shown below.
> Put("PLease enter a number between 1 and 6");
> Get_Line(Item=>Input,Last=>Last);
> if Is_Digit(Input(1..1)) then
You could write
if Ada.Characters.Handling.Is_Digit (Input (Input'First) ) then
rather than writing your own function.
> N:=Integer'Value(Input(1..1));
> if N>=1 and N<=6 then
if N in 1 .. 6 then
> Success:=True;
> end if;
> else
> success:=false;
> Put_Line("Invalid entry, try again.");
> end if;
> end loop;
> Put_Line("Thank you");
> exception
> when others=>
> Put_Line("Error, Invalid data.");
> end;
If the user enters "60" you're going to interpret it as 6, and if " 1"
will be an error. Is that really what you want? Doing
subtype Valid_Number is Integer range 1 .. 6;
N : Valid_Number;
...
N := Integer'Value (Input (Input'First .. Last) );
will reject "60" (not in range) and interpret " 1" as 1.
You can write what you have as:
subtype Valid_Number is Integer range 1 .. 6;
N : Valid_Number;
...
Get_Number : loop
-- Get_Line
Check : begin
N := Integer'Value (Input (Input'First .. Last) );
exit Get_Number;
exception -- Check
when others =>
-- Error message
end Check;
end loop Get_Number;
which seems a lot shorter and clearer (though admittedly some of the
simplification comes from changing how the input is interpreted). It may
take you a little while to become comfortable with Ada to the point that
you come up with things like the above rather than the more complicated
version you have, so don't get discouraged.
>
> Is_Digit a hack of a procedure that compares the 1 character string to all
> 10 digits characters. I really have a lot to learn. What's giving me the
> hardest time is working within the confines of strict/strong typing. The
> Ada.Characters.Handling package already has an Is_Digit function, but it's
> expecting a character not a single item String array! How can I convert
> from one into the other? I have the distinct feelling like I'm reinventing
> the wheel. Aren't packages aready made to do alot of this
> converting/validation? If so where are they? How can one access them?
Type String is an array of type Character, so Input (N) is of type
Character. See my suggestion above.
> Does the RM list all the packages provided by Ada or are there more to be
> discovered?
The ARM lists all the standard packages that come with all compilers.
There are lots of other packages available. www.adapower.com is probably
a good place to start if you want to find others.
--
Jeff Carter
"I wave my private parts at your aunties."
Monty Python & the Holy Grail
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Newbie question on Ada TExt_IO
2002-10-04 20:07 ` Jeffrey Carter
@ 2002-10-07 8:26 ` Fraser Wilson
2002-10-07 19:44 ` Jeffrey Carter
0 siblings, 1 reply; 27+ messages in thread
From: Fraser Wilson @ 2002-10-07 8:26 UTC (permalink / raw)
Jeffrey Carter <jrcarter@acm.org> writes:
> subtype Valid_Number is Integer range 1 .. 6;
> N : Valid_Number;
> ...
> N := Integer'Value (Input (Input'First .. Last) );
Should this be
N := Valid_Number'Value (Input (Input'First .. Last));
?
(Pedantor is in the building)
Fraser.
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Newbie question on Ada TExt_IO
2002-10-07 8:26 ` Fraser Wilson
@ 2002-10-07 19:44 ` Jeffrey Carter
0 siblings, 0 replies; 27+ messages in thread
From: Jeffrey Carter @ 2002-10-07 19:44 UTC (permalink / raw)
Fraser Wilson wrote:
> Jeffrey Carter <jrcarter@acm.org> writes:
>
>>subtype Valid_Number is Integer range 1 .. 6;
>>N : Valid_Number;
>>...
>>N := Integer'Value (Input (Input'First .. Last) );
>
> Should this be
>
> N := Valid_Number'Value (Input (Input'First .. Last));
The ARM defines 'Value as
For every scalar subtype S:
S'Value denotes a function with the following specification:
function S'Value(Arg : String) return S'Base
Since Valid_Number'Value returns Valid_Number'Base, and Valid_Number is
a subtype of Integer, the 2 are equivalent.
--
Jeff Carter
"Have you gone berserk? Can't you see that that man is a ni?"
Blazing Saddles
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Newbie question on Ada TExt_IO
2002-10-04 17:34 ` Justin Birtwell
` (2 preceding siblings ...)
2002-10-04 20:07 ` Jeffrey Carter
@ 2002-10-05 2:43 ` SteveD
2002-10-05 5:25 ` tmoran
3 siblings, 1 reply; 27+ messages in thread
From: SteveD @ 2002-10-05 2:43 UTC (permalink / raw)
"Justin Birtwell" <jbirtwell@yahoo.com> wrote in message
news:Sikn9.1513$Mw4.1034@nwrddc01.gnilink.net...
> Is_Digit a hack of a procedure that compares the 1 character string to all
> 10 digits characters. I really have a lot to learn. What's giving me
the
> hardest time is working within the confines of strict/strong typing. The
> Ada.Characters.Handling package already has an Is_Digit function, but
it's
> expecting a character not a single item String array! How can I convert
> from one into the other? I have the distinct feelling like I'm
reinventing
> the wheel. Aren't packages aready made to do alot of this
> converting/validation? If so where are they? How can one access them?
> Does the RM list all the packages provided by Ada or are there more to be
> discovered?
>
First, if you happen to be using GNAT on windows, go to the help file "Ada
95 Reference Manual". Select "Annexes", then "Annex A: Predefined Language
Environment", then "A. Predefined Language Environment".
Or you can go to http://www.adaic.org/standards/95lrm/html/RM-A.html which
has the same information.
This page shows the standard libraries include in Ada 95. I recommend
perusing these to see what is available.
Second... about your program. It runs if you change the Input_Data( 1..1)
to Input_Data(1) and add a couple of "with" and "use" clauses to make the
built in library function available... but... If you enter "42" the program
is happy and recognizes the value entered as "4". Hmmm... I suspect not
what the user would expect.
Try this one (and please reassure me that this is not a homework assignment
I just completed for you)
with Ada.Text_Io;
use Ada.Text_Io;
with Ada.Strings;
use Ada.Strings;
with Ada.Strings.Fixed;
use Ada.Strings.Fixed;
procedure Test_IO_3 is
Input: String(1..256);
Last:Integer;
result : Integer;
begin
ReadLoop:
loop
Put("Please enter a number between 1 and 6 > ");
Get_Line(Item=>Input,Last=>Last);
declare
Input_Data : String := Trim( Input( 1 .. Last ), Both );
begin
if Input_Data'Length = 1 and then
Input_Data(1) in '1' .. '6' then
result := Integer'Value( Input_Data( 1 .. 1 ) );
Exit ReadLoop;
end if;
Put_Line("Invalid entry, try again.");
end;
end loop ReadLoop;
Put_Line("Thank you");
exception
when others=>
Put_Line("Error, Invalid data.");
end Test_IO_3;
> thanks to one and all,
> Justin
>
>
>
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Newbie question on Ada TExt_IO
2002-10-05 2:43 ` SteveD
@ 2002-10-05 5:25 ` tmoran
0 siblings, 0 replies; 27+ messages in thread
From: tmoran @ 2002-10-05 5:25 UTC (permalink / raw)
If "2.3" is not "a number between 1 and 6", then why allow " +0002 "?
Why not tell the user exactly what you want:
loop
Put("Please enter a digit between 1 and 6 > ");
Get_Line(Item=>Input,Last=>Last);
exit when Last = 1 and then Input(1) in '1' .. '6';
Put_Line("Invalid entry, try again.");
end loop;
result := Integer'Value( Input_Data( 1 .. 1 ) );
Put_Line("Thank you");
^ permalink raw reply [flat|nested] 27+ messages in thread