Ada.Text_IO.Float_IO.get()的行为不符合预期

时间:2018-05-06 20:26:23

标签: ada

我在学习Ada大约5个小时。我制作了一个简单的程序,我在其中加入了不同的值,并且经验丰富,我无法解释。

我的程序可以正常输入,如km = 100,升= 10,结果= 10.0。

显然糟糕的投入工作:km =" cat"导致"提出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;

确切输出:

该程序计算燃油经济性。

输入km:

100..10

输入升数:

您的燃油经济性为每100公里0.10升。

[2018-05-06 14:08:16]流程终止成功,已用时间:04.01s

我在Windows 7上使用GPS 2017。

非常感谢。

3 个答案:

答案 0 :(得分:3)

通常有经验的Ada用户将整行读入String(使用函数Get_Line),然后从String中提取数值。由于这样的程序通常循环直到用户输入有效值,因此读取字符串可以避免直接数字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

答案 1 :(得分:2)

一种解决方案是在读取(前导)数字之后丢弃剩下的行:

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;

答案 2 :(得分:1)

根据Ada Language Reference Manual A.10.9(15-16)您的运行时库的行为正确,因为这两种格式是root@a9c0fde612a1:/# ping -c 1 projweb PING projweb (172.30.0.4) 56(84) bytes of data. 64 bytes from svc_web_1.spp (172.30.0.4): icmp_seq=1 ttl=64 time=0.082 ms --- projweb ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.082/0.082/0.082/0.000 ms 的允许语法:

  • [+ | - ]标记[指数]
  • [+ | - ]标记[指数]