Ada.Text_IO.Float_IO.get() 未按预期运行
Ada.Text_IO.Float_IO.get() not behaving as expected
我学习 Ada 大约需要 5 个小时。我制作了一个简单的程序,我将不同的值放入其中并经历了我无法解释的行为。
我的程序可以正常输入,例如 km = 100、升 = 10、结果 = 10.0。
显然错误的输入有效:km = "cat" 导致 "raised ADA.IO_EXCEPTIONS.DATA_ERROR"
但是这种输入组合让我感到困惑:km = 100..10。该程序跳过升输入并显示一个返回到升值 0.10 的结果。当我输入 'cat'.
时,我期待出现约束错误
谁能给我解释一下这个以及 Ada 程序员是如何解决这个问题的,这样 100..10 就会导致错误。
这是我的程序:
-- This program takes km driven and litres consumed to calculate
-- fuel economy.
with Ada.Text_IO;
with Ada.Float_Text_IO;
procedure Main is
package TIO renames Ada.Text_IO;
package FIO renames Ada.Float_Text_IO;
type Km is new Float range 0.01 .. 10_000.00;
type Litres is new Float range 0.01 .. 10_000.00;
package Km_IO is new TIO.Float_IO (Km);
package Litres_IO is new TIO.Float_IO (Litres);
Entered_Km : Km;
Entered_Litres : Litres;
function Fuel_Economy (
Entered_Km : in Km;
Entered_Litres : in Litres
) return Float is
-- returns fuel economy normalized to litres per 100 km
begin
return Float(Entered_Litres) / Float(Entered_Km) * 100.0;
end Fuel_Economy;
begin
TIO.Put_Line ("This program calculates fuel economy.");
TIO.Put_Line ("Enter km:");
Km_IO.Get (Entered_Km);
TIO.Put_Line ("Enter litres:");
Litres_IO.Get (Entered_Litres);
TIO.Put ("Your fuel economy is ");
FIO.Put (Item => Fuel_Economy (Entered_Km, Entered_Litres),
Fore => 1,
Aft => 2,
Exp => 0
);
TIO.Put_Line (" litres per 100 km.");
end Main;
精确输出:
此程序计算燃油经济性。
输入公里数:
100..10
输入升:
您的燃油经济性是每 100 公里 0.10 升。
[2018-05-06 14:08:16]进程成功终止,耗时:04.01s
我在 windows 7.
上使用 GPS 2017
非常感谢。
根据 Ada Language Reference Manual A.10.9(15-16),您的 运行-time 库运行正常,因为这两种格式是 Ada.Text_IO.Float_IO.Get
:
允许的语法
- [+|–]数字.[指数]
- [+|–].数字[指数]
一个解决方案是在读取(前导)数字后丢弃该行的其余部分:
TIO.Put_Line ("Enter km:");
Km_IO.Get (Entered_Km);
TIO.Skip_Line;
另一个不那么直接的方法是检查是否没有遗留任何东西:
TIO.Put_Line ("Enter km:");
Get_Km:
loop
declare
Input : constant String := TIO.Get_Line;
Last : Natural;
begin
Km_IO.Get (From => Input, Item => Entered_Km, Last => Last);
exit Get_Km when Input (Last + 1 .. Input'Length)
= (Last + 1 .. Input'Length => ' ');
TIO.Put_Line ("... just the number, please; '"
& Input (Last + 1 .. Input'Length)
& "' was left over");
exception
when others =>
TIO.Put_Line ("... a number, please");
end;
end loop Get_Km;
通常有经验的 Ada 用户将整行读入一个字符串(使用函数 Get_Line),然后从该字符串中提取数值。由于像这样的程序通常会循环直到用户输入有效值,因此读入字符串可避免直接数字 I/O 的常见问题,其中无效输入会导致无限循环:
Get_Km : loop
Handle_Invalid : begin
Put_Line (Item => "Enter km");
Get (Item => Entered_Km);
exit Get_Km;
exception -- Handle_Invalid
when others =>
Put_Line ("Invalid input");
end Handle_Invalid;
end loop Get_Km;
无效输入保留在缓冲区中,并被Get重复处理。
Wright 展示了这种变体,但通常在丢弃值后留在行中的任何内容,以便可以从带有尾随注释的文件中重定向输入:
13.3 -- km traveled
我学习 Ada 大约需要 5 个小时。我制作了一个简单的程序,我将不同的值放入其中并经历了我无法解释的行为。
我的程序可以正常输入,例如 km = 100、升 = 10、结果 = 10.0。
显然错误的输入有效:km = "cat" 导致 "raised ADA.IO_EXCEPTIONS.DATA_ERROR"
但是这种输入组合让我感到困惑:km = 100..10。该程序跳过升输入并显示一个返回到升值 0.10 的结果。当我输入 'cat'.
时,我期待出现约束错误谁能给我解释一下这个以及 Ada 程序员是如何解决这个问题的,这样 100..10 就会导致错误。
这是我的程序:
-- This program takes km driven and litres consumed to calculate
-- fuel economy.
with Ada.Text_IO;
with Ada.Float_Text_IO;
procedure Main is
package TIO renames Ada.Text_IO;
package FIO renames Ada.Float_Text_IO;
type Km is new Float range 0.01 .. 10_000.00;
type Litres is new Float range 0.01 .. 10_000.00;
package Km_IO is new TIO.Float_IO (Km);
package Litres_IO is new TIO.Float_IO (Litres);
Entered_Km : Km;
Entered_Litres : Litres;
function Fuel_Economy (
Entered_Km : in Km;
Entered_Litres : in Litres
) return Float is
-- returns fuel economy normalized to litres per 100 km
begin
return Float(Entered_Litres) / Float(Entered_Km) * 100.0;
end Fuel_Economy;
begin
TIO.Put_Line ("This program calculates fuel economy.");
TIO.Put_Line ("Enter km:");
Km_IO.Get (Entered_Km);
TIO.Put_Line ("Enter litres:");
Litres_IO.Get (Entered_Litres);
TIO.Put ("Your fuel economy is ");
FIO.Put (Item => Fuel_Economy (Entered_Km, Entered_Litres),
Fore => 1,
Aft => 2,
Exp => 0
);
TIO.Put_Line (" litres per 100 km.");
end Main;
精确输出:
此程序计算燃油经济性。
输入公里数:
100..10
输入升:
您的燃油经济性是每 100 公里 0.10 升。
[2018-05-06 14:08:16]进程成功终止,耗时:04.01s
我在 windows 7.
上使用 GPS 2017非常感谢。
根据 Ada Language Reference Manual A.10.9(15-16),您的 运行-time 库运行正常,因为这两种格式是 Ada.Text_IO.Float_IO.Get
:
- [+|–]数字.[指数]
- [+|–].数字[指数]
一个解决方案是在读取(前导)数字后丢弃该行的其余部分:
TIO.Put_Line ("Enter km:");
Km_IO.Get (Entered_Km);
TIO.Skip_Line;
另一个不那么直接的方法是检查是否没有遗留任何东西:
TIO.Put_Line ("Enter km:");
Get_Km:
loop
declare
Input : constant String := TIO.Get_Line;
Last : Natural;
begin
Km_IO.Get (From => Input, Item => Entered_Km, Last => Last);
exit Get_Km when Input (Last + 1 .. Input'Length)
= (Last + 1 .. Input'Length => ' ');
TIO.Put_Line ("... just the number, please; '"
& Input (Last + 1 .. Input'Length)
& "' was left over");
exception
when others =>
TIO.Put_Line ("... a number, please");
end;
end loop Get_Km;
通常有经验的 Ada 用户将整行读入一个字符串(使用函数 Get_Line),然后从该字符串中提取数值。由于像这样的程序通常会循环直到用户输入有效值,因此读入字符串可避免直接数字 I/O 的常见问题,其中无效输入会导致无限循环:
Get_Km : loop
Handle_Invalid : begin
Put_Line (Item => "Enter km");
Get (Item => Entered_Km);
exit Get_Km;
exception -- Handle_Invalid
when others =>
Put_Line ("Invalid input");
end Handle_Invalid;
end loop Get_Km;
无效输入保留在缓冲区中,并被Get重复处理。
Wright 展示了这种变体,但通常在丢弃值后留在行中的任何内容,以便可以从带有尾随注释的文件中重定向输入:
13.3 -- km traveled