Ada:获取整数时如何管理Data_error异常



例如,我试图让用户从菜单中选择一种模式

现在我可以使用调用获取整数输入

ada.integer_text_io.get(integer_variable);

这里的主要问题是,如果我插入非数字字符串(例如字符串),则会引发以下异常

raised ADA.IO_EXCEPTIONS.DATA_ERROR : a-tiinio.adb:89 instantiated at a-inteio.ads:18

尝试接收一个字符,检查它是否是整数,然后将其转换为整数,但后来我意识到我需要获取大于 1 位的整数的输入,因此字符方法不起作用。

如果我收到一个字符串,那么我无法检查它是否是整数(除非我扫描整个字符串以查看它的所有字符是否都是整数......

除了扫描整个字符串之外,还有其他解决方案吗?或者也许是一种异常处理技术,可能会阻止程序终止并再次请求适当的整数?

-CH

几乎所有在

Ada 中将字符串解析为某种标量值的标准方法都会在/如果读取无效字符串时产生某种异常。这没有任何问题。只需处理异常。

即使您编写了自己的字符串解析到整数例程,您也必须以某种方式处理用户输入无效字符串的情况。右?

我想唯一涉及的"技术"是您可以将异常处理程序放在子例程上,甚至可以放在代码中内联的declare ... begin ... end块上。这样,只有块中的代码被中止。一般来说,我更喜欢看到使用的子程序。所以你会得到这样的东西:

function User_Integer return Integer is
begin
    loop
        begin
            ada.integer_text_io.get(integer_variable);
            return integer_variable;
        exception
            when ADA.IO_EXCEPTIONS.DATA_ERROR =>
                Ada.Text_IO.Put_Line ("Try a number from 1 to 3, Sherlock");
                Print_Menu;
        end;
    end loop;
end User_Integer;

现在,在这种情况下,对于快速而肮脏的 Ada 菜单,我通常不会像上面那样做数字菜单。而是创建一个枚举类型。这样,您就可以在菜单类型中循环使用'image打印菜单选项,当您使用 'valueAda.Text_IO.Enumeration_IO 时,Ada 将处理文本解析。

type Menu_Selection_Option is (Eat, Drink, Sleep);
package Menu_IO is new Ada.Text_IO.Enumeration_IO (Menu_Selection_Option);
function User_Selection return Integer is
begin
    loop
        declare
            Selection : Menu_Selection_Option;
        begin
            Menu_IO.Get(Selection);
            return Selection;
        exception
            when ADA.IO_EXCEPTIONS.DATA_ERROR =>
                Ada.Text_IO.Put_Line ("Unrecognized option. Try again Sherlock");
                Print_Menu;
        end;
    end loop;
end User_Selection;

这样做的好处是,当菜单选项列表更改时,您不必更改菜单打印代码或解析代码。

用于请求此类用户输入的主要 Ada 编程习惯用法Get_Line:

procedure Get_Line(Item : out String;   Last : out Natural);

function Get_Line return String;

现在,用户的响应位于字符串中,您可以快速扫描非数字字符,或使用 Integer'Value 属性将其转换为整数(将调用包装在合适的异常处理程序中)。 例如:

loop
   Put_Line("What do you want to do?");
   Display_Options;
   declare
      What_To_Do : Positive;
      Response : String(1..20);
      Last     : Natural;
   begin
      Get_Line(Response, Last);
      exit when Last = 0;
      What_To_Do := Integer'Value(Response(1 .. Last));  --' Buggy highlight fix
      Go_Do_Something(What_To_Do);
   exception
      when Data_Error =>
         Put_Line("Invalid response, try again...");
   end;
end loop;

这个习惯用法的另一个优点是,你也可以接受非数字输入,例如"Q"表示 Quit,或"Quit";还可以执行可能需要的任何字符预处理,如大小写。

您可以处理异常,可以在循环中重复请求输入,直到输入整数,或者在末尾优雅地退出......

相关内容

  • 没有找到相关文章

最新更新