Compare a string input to an Enumerated type

2020-03-07 08:25发布

问题:

I am looking to do a comparison of a string to and enumeration. I have written a sample code of what I am attempting. Since a String and and Enumerated type are different, how do I go about doing this properly in Ada?

WITH Ada.Text_IO; USE Ada.Text_IO;

PROCEDURE ColorTest IS

   TYPE StopLightColor IS (red, yellow, green);

   response : String (1 .. 10);
   N : Integer;

BEGIN
   Put("What color do you see on the stoplight? ");
   Get_Line (response, N);
   IF response IN StopLightColor THEN
      Put_Line ("The stoplight is " & response(1..n));
   END IF;

END ColorTest;

回答1:

First instantiate Enumeration_IO for StopLightColor:

package Color_IO is new Ada.Text_IO.Enumeration_IO(StopLightColor);

Then you can do either of the following:

  • Use Color_IO.Get to read the value, catching any Data_Error that arises, as shown here for a similar instance of Enumeration_IO.

  • Use Color_IO.Put to obtain a String for comparison to response.

As an aside, Stoplight_Color might be a more consistent style for the enumerated type's identifier.



回答2:

Another possibility:

Get_Line (response, N);
declare
    Color : StopLightColor;
begin
    Color := StopLightColor'Value(response(1..N));
    -- if you get here, the string is a valid color
    Put_Line ("The stoplight is " & response(1..N));
exception
    when Constraint_Error =>
        -- if you get here, the string is not a valid color (also could
        -- be raised if N is out of range, which it won't be here)
        null;
end;


回答3:

Answering your actual question:

Ada doesn't allow you to compare values of different types directly, but luckily there is a way to convert an enumerated type to a string, which always works.

For any enumerated type T there exists a function:

function T'Image (Item : in T) return String;

which returns a string representation of the enumerated object passed to it.

Using that, you can declare a function, which compares a string and an enumerated type:

function "=" (Left  : in String;
              Right : in Enumerated_Type) return Boolean is
begin
   return Left = Enumerated_Type'Image (Right);
end "=";

If you want to do a case-insensitive comparison, you could map both strings to lower case before comparing them:

function "=" (Left  : in String;
              Right : in Enumerated_Type) return Boolean is
   use Ada.Characters.Handling;
begin
   return To_Lower (Left) = To_Lower (Enumerated_Type'Image (Right));
end "=";


标签: ada