1

I am trying to have a program that takes a number from the user (from 1 - 12) and it will return that month's short form, eg: if you write 1 it will return JAN etc.

I have the following:

type Month_Type is (JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC);

but how do I link this to userMonth : Integer;. I thought something like Month_Type(userMonth) but this didn't work and gave me errors. The only other thing I can think of is to have a loop for each Month_Type and have a counter in there so that it matches. But this seems messy and not very efficient, there must be a better way.

Aequitas
  • 2,205
  • 1
  • 25
  • 51
  • Homework? You might be interested in the positions that `JAN` and to forth have in the type. For that, have a look at the 'Pos attribute. Or simply use a conditional that reflects what you wrote: **if** … 1 **then** … **return** `JAN`… – B98 Mar 10 '17 at 06:19
  • 3
    Why are you using `Integer` for the input? If the user only is allowed to enter `1 .. 12`, then you should use an appropriate type: `type Month_Number is range 1 .. 12;`. – Jacob Sparre Andersen Mar 10 '17 at 06:49
  • @JacobSparreAndersen what benefits will that have? What if a 13 is entered? will it error out? – Aequitas Mar 11 '17 at 03:24
  • Exactly. So you avoid incorrect entries. – Jacob Sparre Andersen Mar 11 '17 at 15:08
  • @JacobSparreAndersen i've started to incorporate your suggestion of using a range, which looks like it makes a subtype of Integer, this means my `Int_Io.get` doesn't work, i'm guessing I need to do a custom type.get, which I can see in your answer below how to do. but I get an error with that, my guess is that is because a range of intgers is not an enumeration_IO. What do I use instead? – Aequitas Mar 15 '17 at 01:31
  • 1
    ... drum-roll ... `Ada.Text_IO.Integer_IO`. :-) When you are programming in Ada, it is useful to have the Ada Language Reference Manual (http://www.ada-auth.org/standards/rm12_w_tc1/html/RM-TTL.html) around for looking such things up. – Jacob Sparre Andersen Mar 15 '17 at 07:24

3 Answers3

7

In Ada you can do it much easier:

with Ada.Text_IO;
procedure Demo is
   type Month_Type is (Jan, Feb, Mar, [...], Dec);
   package Month_Text_IO is new Ada.Text_IO.Enumeration_IO (Month_Type);
   Input : Month_Type;
begin
   Month_Text_IO.Get (Input);
end Demo;

No need to handle integer values in between.

Jacob Sparre Andersen
  • 6,733
  • 17
  • 22
4

Among the Operations of Discrete Types, the attribute 'Val denotes a function that returns a value of the type Month_Type whose position number equals the value of the argument passed to it. For example, the expression Month_Type'Val(0) would evaluate to JAN.

Note that the internal code used by the attribute is unaffected by an Enumeration Representation Clause. Given a declaration such as userMonth : constant := 1, use the expression Month_Type'Val(userMonth - 1).

When using a representation clause with GNAT, the implementation defined attribute 'Enum_Val denotes a function that "returns the enumeration value whose representation matches the argument." Using the representation clause suggested here, the expression Month_Type'Enum_Val(userMonth) would evaluate to JAN without adjustment.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
3

As a complement of the other answers, you can also use the Ada representation clauses to match your enumerate with the intput/output values that you like.

This is useful if you need to interface your code with other software that might be not coded in Ada.

There are a few limitations with this : if my memories are good, you need to have ascending numbers.

So :

type Month_Type is (JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC);
for Month_Type use (
        JAN => 1,
        FEB => 2,
        ...);
LoneWanderer
  • 3,058
  • 1
  • 23
  • 41