如何检查输入?阿达语

问题描述

我刚刚开始学习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;

我不是应该使用“范围”来检查输入,而是如果某些使用>,

我的另一种方法是尝试使用异常,但这也无法正常工作,

  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来引用匿名基类型。

自从您使用Score声明了range以来,它是一个带符号的整数类型,并且其基本类型(大约)对称于零。所以您的声明等同于

type Score'Base is range -128 .. 127;
subtype Score is Score'Base range 0 .. 100;

(这不是Ada,也不会编译)。

Score'Value返回值Score'BaseARM 3.5 (53)),因此,如果输入"101""-3",则Score'Value将成功并返回适当的值。当您将该值分配给子类型Score的变量时,将检查该值是否在Score的范围内;如果失败,将引发Constraint_Error。如果输入无效的图像,例如"200""xyz",则Score'Value会失败并引发Constraint_Error。因此,您有两种错误的输入,会导致两种不同的失败,而这两种错误恰巧都会引发相同的异常。

您的第一个版本失败了,因为您从未接触过if语句。您的第二个版本失败了,因为Ada.Text_IO.Get_Line从不提高Data_Error

在处理数字输入时,我建议将整行读入字符串,然后像完成操作一样从该字符串中解析出值。但是,'Value将拒绝您可能希望视为有效的某些输入。例如,您可能想要接受"23 skidoo"并从中获取值23。为此,您可能想为数字(子)类型实例化Ada.Text_IO.Integer_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)中From的索引。

HTH