如何检查输入?阿达语
How to check the input? Ada language
我刚开始学习 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
)是first-named子类型的名字. first-named 子类型可能具有不适用于匿名基类型的约束。对于某些类型,包括整数类型,可以使用 'Base
.
来引用匿名基类型
由于您使用 range
声明了 Score
,因此它是一个带符号的整数类型,其基类型(大致)围绕零对称。所以你的声明相当于
type Score'Base is range -128 .. 127;
subtype Score is Score'Base range 0 .. 100;
(这不是 Ada,不会编译)。
Score'Value
returns 的值为 Score'Base
(ARM 3.5 (53)),因此如果您输入 "101"
或 "-3"
,Score'Value
将成功并且 return 适当的值。当您将该值分配给子类型 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
并使用带有 String
参数的 Get
函数:
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
设置为 From
(2) 中 '3'
的索引。
HTH
我刚开始学习 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
)是first-named子类型的名字. first-named 子类型可能具有不适用于匿名基类型的约束。对于某些类型,包括整数类型,可以使用 'Base
.
由于您使用 range
声明了 Score
,因此它是一个带符号的整数类型,其基类型(大致)围绕零对称。所以你的声明相当于
type Score'Base is range -128 .. 127;
subtype Score is Score'Base range 0 .. 100;
(这不是 Ada,不会编译)。
Score'Value
returns 的值为 Score'Base
(ARM 3.5 (53)),因此如果您输入 "101"
或 "-3"
,Score'Value
将成功并且 return 适当的值。当您将该值分配给子类型 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
并使用带有 String
参数的 Get
函数:
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
设置为 From
(2) 中 '3'
的索引。
HTH