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

发布于 2024-11-07 17:05:13 字数 551 浏览 4 评论 0原文

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

  1. Eat
  2. Drink
  3. Sleep

现在我可以通过使用调用获得整数输入

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

I'm trying to make the user select a mode from the menu for example

  1. Eat
  2. Drink
  3. Sleep

Now I can get an integer input by using the call

ada.integer_text_io.get(integer_variable);

The main problem here is that if I insert a non digit string(such as a character string) the following exception is raised

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

I've tried receiving a character, check if it is a integer, then convert it into a integer, but then I realized that I need to get inputs for integer larger than 1 digits, so the character method won't work.

If I receive a string, then I can't check to see if it is a integer or not(unless i scan through the whole string to see if all its characters are integer...)

Is there another solution other than scanning the whole string?
Or perhaps a exception handling technique that might keep the program from terminating and ask again for a proper integer?

-CH

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

杯别 2024-11-14 17:05:13

当/如果读取无效字符串时,几乎所有在 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 打印菜单选项,当您使用 'value时,Ada 将处理文本解析Ada.Text_IO.Enumeration_IO

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;

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

Pretty much all the standard ways to parse a string into a scalar value of some kind in Ada will produce an exception of some kind when/if an invalid string is read. There isn't anything wrong with that. Just handle the exception.

Even if you wrote your own string parsing to integer routines, you'd have to somehow handle the situation where the user entered an invalid string. Right?

I guess the only "technique" involved is that you can put exception handlers on subroutines, or even on declare ... begin ... end blocks that you put inline in your code. This way only the code within the block is aborted. Generally I prefer to see subroutines used. So you'd get something like:

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;

Now, this being the case, for quick-and-dirty Ada menus I generally don't do numeric menus like above. Instead, make an enumerated type. That way you can print the menu options using a 'image in a loop through the menu type, and Ada will handle the text parsing when you use 'value or Ada.Text_IO.Enumeration_IO.

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;

The nice thing about this is that you don't have to change your menu-printing code or your parsing code when the list of menu options changes.

彩扇题诗 2024-11-14 17:05:13

用于请求此类用户输入的主要 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”表示退出,或“退出”;并且还进行可能需要的任何字符预处理,例如大小写。

The predominant Ada programming idiom for requesting user input of this sort uses Get_Line:

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

or

function Get_Line return String;

Now that the user's response is in a string you can do a quick scan for non-numeric characters, or use the Integer'Value attribute to convert it to an integer (wrapping the invocation in a suitable exception handler). For example:

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;

The added advantage of this idiom is that you can accept non-numeric input as well, such as 'Q' for Quit, or "Quit"; and also do any character preprocessing, like up-casing, that might be needed.

迷路的信 2024-11-14 17:05:13

您可以处理异常,要么在循环中重复请求输入,直到输入整数,要么在结束时优雅地退出......

You can handle the exception, either within a loop to repeatedly ask for input until an integer is entered, or towards the end to exit gracefully...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文