2

从文件读取输入'Size'Component_Size尝试使用Unchecked_Conversion. 我知道要成功使用Unchecked_ConversionSource 和 Target 需要相同size。我正在从文件中读取输入,000100000101001并希望使用 Unchecked Conversion 将其放入位数组中。但是,转换似乎总是失败,因为它们的大小不同或太小。

    with Ada.Unchecked_Conversion;
    with Ada.Text_IO; use Ada.Text_IO;
    with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

    procedure main is
        type Bit is mod 2 with size => 1;
        type Bit_Array is array(Positive range <>) of Bit with pack;
        subtype Bit15 is Bit_Array(1 .. 15); //subtypes because can't use conversion on unconstrainted type
        subtype Bit11 is Bit_Array(1 .. 11);

        function StringA_to_Bit15 is
           new Ada.Unchecked_Conversion(source => String, target => Bit15);


        begin
        while not end_of_file loop
            declare
                s: String := get_line; //holding first line of input
                len: constant Natural := (if s'length-3 = 15 
                                        then 15
                                        else 11); 
                i: Integer;
                ba: Bit_Array(1 .. len); //constrain a Bit_Array based on length of input
            begin
                ba := String_to_Bit15(s);
                new_line;
            end;
        end loop;

这是我的类型,位只能是 0 或 1size到 1 位。Bit_Array 只是一个不受约束的位数组,因为我的输入可以是 15 位长或 11 位长。我的想法是将第一行读入字符串并将其转换为 Bit_Array。这不起作用,因为 String 和其他所有原始类型都不是Size => 1. 所以很自然地,我想创建一个新类型来处理这个我尝试过的形式,创建我自己的字符串类型并设置size => 1但字符需要 8 位。我需要创建什么数据类型来读取一行数据并将其转换为适合 Bit_Array?我可能正在接近这个错误,但它对我来说非常混乱。任何帮助或提示表示赞赏!

4

2 回答 2

5

您不能使用Unchecked_Conversion,因为正如您所发现的, aCharacter不对应于 a BitCharacter对应的 8 位 ASCII0具有对应十进制值 48 的位模式,1值为 49。

我认为你必须硬着头皮循环输入字符串。执行此操作的简单函数,要求输入字符串仅包含0s 和1s,可能是

function To_Bit_Array (S : String) return Bit_Array is
   Input : constant String (1 .. S'Length) := S;
   Result : Bit_Array (1 .. S'Length);
begin
   for J in Input'Range loop
      Result (J) := (case Input (J) is
                        when '0' => 0,
                        when '1' => 1,
                        when others => raise Constraint_Error);
   end loop;
   return Result;
end To_Bit_Array;

(声明 of 的重点Input是确保J两个数组的索引相同; a 的第一个索引String只需为Positive,即大于 0)。

于 2019-03-25T22:19:36.670 回答
0

但是,如果您要从模块化整数类型转换为位数组,则可以使用 Unchecked_Conversion。我通常避免使用 Unchecked_Conversion 除非作为最后的手段,但我可以看到从整数转换为位数组类型的诱惑。但是,我也会考虑是否只使用模整数,因为它也可以用于按位运算。不过,使用数组语法访问位是一个不错的功能。即使我想将模块化整数转换为位数组,我仍然建议尽可能避免使用 Unchecked_Conversion 或 Ada 中的几乎 Unchecked_ 任何东西。一个原因是 Unchecked_Conversion 可能不太便携。例如,不同的编译器和不同的目标可能以不同的顺序存储位。

另一个建议是使用打包的布尔数组,而不是打包的位数组。内存中的存储应该看起来相同,但我认为您会发现使用布尔值而不是位更方便。它使您不必将值与 1 或 0 进行比较。

因此,将输入字符串转换为模整数的一种方法是使用 Ada.Text_IO.Modular_IO 包。

type Short is mod 2**16;

package Short_IO is new Modular_IO (Num => Short);

type Bit_Array is array (Positive range <>) of Boolean
  with Component_Size => 1;
...

declare
     Input : constant String := Get_Line;
     Value : Short := 0;
     Last  : Positive;
     Bits_11 : Bit11;

     -- Instead of using Unchecked_Conversion, consider writing a 
     -- simple conversion function
     --
     function To_Bit11 (Value : Short) return Bit11 is
        ((for I in Bit11'Range => (Short(2**(I-1)) and Value) /= 0));

  begin

     --  Enclosing the input string with 2#{binary_string}#, 
     --  causes the number to be read in base 2, as a binary text
     --  string.
     Short_IO.Get (From  => "2#" & Input & "#",
                   Item  => Value,
                   Last  => Last);

     --  You could use unchecked conversion here to convert
     --  to the Bit array, but I'd recommend doing this
     --  without using unchecked features of the language
     --  e.g. using a simple loop

     for I in Bits_11'Range loop
        Bits_11 (I) := (Short(2**(I-1)) and Value) /= 0;
     end loop;

     --  or you can even try an Ada 2020 feature that already has
     --  been implemented in the latest community edition of GNAT.
     --  By assigning a new form of array aggregate to the 
     --  bit array object. You'd need to set the -gnatX compiler
     --  option to tell the compiler to use Ada extended 2020
     --  features. Many Ada 2020 features are not yet available to try
     --  out, but this one is available.

     Bits_11 :=
        (for I in Bits_11'Range => (Short (2**(I-1)) and Value) /= 0);

     -- or combine this into an expression function like above,
     -- then you have a function similar to the one you'd get using
     -- Unchecked_Conversion, except more portable, and one can
     -- examine the code to understand the implementation.

     Bits_11 := To_Bit11 (Value);
于 2019-03-28T14:30:22.600 回答