例如,我试图让用户从菜单中选择一种模式
- 吃
- 喝
- 睡
现在我可以使用调用获取整数输入
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
打印菜单选项,当您使用 'value
或 Ada.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";还可以执行可能需要的任何字符预处理,如大小写。
您可以处理异常,可以在循环中重复请求输入,直到输入整数,或者在末尾优雅地退出......