Exception 如何检查输入?Ada语言

Exception 如何检查输入?Ada语言,exception,input,ada,Exception,Input,Ada,我刚刚开始学习Ada,当用户输入超出变量的声明范围时,我不知道如何保持程序运行。我想打印输入错误范围的信息,然后再次要求用户输入 这是我的简单代码: with Ada.Text_IO; use Ada.Text_IO; procedure Main is type Score is range 0..100; a : Score; begin Put_Line ("Enter value range 0-100: "); a :=

我刚刚开始学习Ada,当用户输入超出变量的声明范围时,我不知道如何保持程序运行。我想打印输入错误范围的信息,然后再次要求用户输入

这是我的简单代码:

with Ada.Text_IO;
use Ada.Text_IO;

procedure Main is
     type Score is range 0..100;
      a : Score;
begin
     Put_Line ("Enter value range 0-100: ");
     a := Score'Value(Get_Line);

     if a'Valid then
          Put_Line ("You entered" & Score'Image (a));
     else
          Put_Line ("Bad range of input");
     end if;
end Main;
我是否应该使用“范围”来检查输入,而是使用带有>,<限制的一些if

我的另一种方法是在例外情况下尝试此方法,但它也不能像我希望的那样工作:

  with Ada.Text_IO;
  with Ada.IO_Exceptions;
  use Ada.Text_IO;

  procedure Main is
     type Score is range 0..100;
     a : Score;
  begin
     loop
        begin
        Put_Line ("Enter value range 0-100: ");
        a := Score'Value(Get_Line);
        Put_Line ("You entered" & Score'Image (a));
        exit;
        exception
           when Ada.IO_Exceptions.Data_Error =>
              Put_Line("Bad range of input");
        end;
     end loop;
  end Main;

我相信问题在于我不理解这种语言,但我希望有一种简单的解决方法,谢谢你的帮助。

现在你知道一种神奇的咒语可以起作用,但我怀疑你是否理解它为什么起作用,或者你的其他咒语为什么不起作用。我将深入探讨这方面令人痛苦的教学细节,希望其中一些内容可能有用或有趣

在Ada中,当您声明一个类型时,该类型是匿名的,您给出的名称(
Score
)是第一个命名子类型的名称。第一个命名的子类型可能具有不适用于匿名基类型的约束。对于某些类型,包括整数类型,可以使用
'base
引用匿名基类型

由于您使用
range
声明了
Score
,因此它是一个有符号整数类型,其基类型(大致)围绕零对称。所以你的声明相当于

type Score'Base is range -128 .. 127;
subtype Score is Score'Base range 0 .. 100;
(这不是Ada,也不会编译)

Score'Value
返回
Score'Base
()的值,因此如果输入
“101”
“-3”
Score'Value
将成功并返回适当的值。当您将该值指定给子类型
得分
的变量时,会检查该值是否在
得分
的范围内;如果失败,将引发约束错误。如果输入无效图像,例如
“200”
“xyz”
分数值
失败并引发
约束错误
。因此,有两种不正确的输入导致两种不同的故障,这两种故障都会引发相同的异常

您的第一个版本失败,因为您从未使用
if
语句。您的第二个版本失败,因为
Ada.Text\u IO.Get\u Line
从未引发
数据错误

在处理数字输入时,我建议将完整的一行读入一个字符串,然后像您所做的那样从该字符串中解析出值。但是,<>代码>值会拒绝一些您可能想考虑的输入。例如,您可能希望接受
“23 skidoo”
,并从中获取值23。为此,您可能希望为您的数字(子)类型实例化
Ada.Text\u IO.Integer\u IO
,并使用
Get
函数,该函数接受
String
参数:

package Score_IO is new Ada.Text_IO.Integer_IO (Num => Score);
...
Score_IO.Get (From => "23 skidoo", Item => A, Last => Last);
A
设置为23,并将
Last
设置为
'3'
的索引(2)


HTH

程序失败时查看报告。可能是对
a
的赋值引发了约束错误,但您正在处理数据错误??是的,这是约束错误!我已将检查异常的行更改为
Ada.IO\u Exceptions.Constraint\u Error
,但现在我得到一个错误,即在IO\u Exceptions中未声明Constraint\u Error。我应该如何包含它?它在系统中已经可见了
When Constraint\u Error=>
谢谢,我不知道,这解决了我的问题。再次感谢:)@obeey只是想补充一些额外的信息:“Valid”用于验证“unchecked”操作,其中范围和约束并不总是被验证。就像使用Unchecked_转换时一样,我倾向于将调用包装为Unchecked_转换,然后调用“Valid”,以确保没有输入错误数据。Ada足够好,可以在以后捕捉到它,但是如果可能的话,我喜欢从源头捕捉问题。