comp.lang.ada
 help / color / mirror / Atom feed
* Newbie question on Ada TExt_IO
@ 2002-10-03 18:20 Justin
  2002-10-03 18:50 ` Matthew Heaney
                   ` (6 more replies)
  0 siblings, 7 replies; 27+ messages in thread
From: Justin @ 2002-10-03 18:20 UTC (permalink / raw)


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

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?

Thanks for they help,
Justin



^ 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
                   ` (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-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  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: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: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 18:00     ` David C. Hoos
@ 2002-10-04 18:04       ` Preben Randhol
  0 siblings, 0 replies; 27+ messages in thread
From: Preben Randhol @ 2002-10-04 18:04 UTC (permalink / raw)


On Fri, 4 Oct 2002 13:00:41 -0500, David C. Hoos wrote:
> 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

You mean: ftp://ftp.ada95.com/pub/pet_store.tgz

-- 
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: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-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 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

* Re: Newbie question on Ada TExt_IO
@ 2002-10-07  6:01 Grein, Christoph
  0 siblings, 0 replies; 27+ messages in thread
From: Grein, Christoph @ 2002-10-07  6:01 UTC (permalink / raw)


when you test your program, try the following inputs (non-exhaustive list)

<Return>
1<Return>
 1<Return>
01<Return>
16<Return>
1 1<Return>
1a<Return>
1 a<Return>
a<Return>
 a<Return>

It's upon you to decide which of the above are valid. Also note that Ada syntax 
for integers includes exponential form: 1E+0 is a valid input for 1.



^ 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:27 Grein, Christoph
  2002-10-07 11:48 ` Fraser Wilson
  0 siblings, 1 reply; 27+ messages in thread
From: Grein, Christoph @ 2002-10-07  8:27 UTC (permalink / raw)


> > 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)

Attributes can use as prefix either the subtype or the type (which in fact is 

is the first named subtype) without difference.



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Newbie question on Ada TExt_IO
  2002-10-07  8:27 Grein, Christoph
@ 2002-10-07 11:48 ` Fraser Wilson
  2002-10-07 12:46   ` Robert A Duff
  0 siblings, 1 reply; 27+ messages in thread
From: Fraser Wilson @ 2002-10-07 11:48 UTC (permalink / raw)


"Grein, Christoph" <christoph.grein@eurocopter.com> writes:

> Attributes can use as prefix either the subtype or the type (which in fact is 
> 
> is the first named subtype) without difference.

Oh, darn.  Thanks.  I missed the 'sub' in 'subtype'.

Though I'd argue that using an attribute of the constrained subtype
would be clearer.  Which is to say I was confused.

cheers,
Fraser.



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Newbie question on Ada TExt_IO
  2002-10-07 11:48 ` Fraser Wilson
@ 2002-10-07 12:46   ` Robert A Duff
  0 siblings, 0 replies; 27+ messages in thread
From: Robert A Duff @ 2002-10-07 12:46 UTC (permalink / raw)


Fraser Wilson <newsfraser@blancolioni.org> writes:

> Though I'd argue that using an attribute of the constrained subtype
> would be clearer.  Which is to say I was confused.

Maybe.  But note that Valid_Number'Value("7") returns 7, even though the
range of Valid_Number is 1..6.  It does not raise Constraint_Error.
*That* could be confusing, too, perhaps.

- Bob



^ 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

end of thread, other threads:[~2002-10-07 19:44 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
2002-10-03 19:43 ` Preben Randhol
2002-10-03 19:55   ` Matthew Heaney
2002-10-03 20:07     ` Preben Randhol
2002-10-04  2:42 ` SteveD
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:02       ` Preben Randhol
2002-10-04 18:34     ` tmoran
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-07 19:44       ` Jeffrey Carter
2002-10-05  2:43   ` SteveD
2002-10-05  5:25     ` tmoran
  -- strict thread matches above, loose matches on Subject: below --
2002-10-07  6:01 Grein, Christoph
2002-10-07  8:27 Grein, Christoph
2002-10-07 11:48 ` Fraser Wilson
2002-10-07 12:46   ` Robert A Duff

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