Ада - Как вы читаете массив из одной строки ввода? - PullRequest
0 голосов
/ 08 декабря 2018

Мой вопрос довольно прост, у меня есть входные данные, которые выглядят так ...

0   0   0   1   1   1  -1  -1  -1   1

И мне нужно сохранить эти значения в массиве, но я не могу понять это.Это то, что у меня есть ...

with Ada.Text_IO; use Ada.Text_IO;

procedure Main is
    type arr is array(1..10) of Integer;
    Data : arr;
begin
    for I in 1..arr'Length loop
        Data(I) := Integer'Value(Get_Line);
    end loop;
end Main;

Я знаю, что это неправильно, и совершенно очевидно, почему это не работает.Я пытаюсь сохранить несколько значений в одно целое число, мне нужен способ перебора ввода или загрузить все значения одновременно.Как бы вы сделали это в Аде?

Ответы [ 3 ]

0 голосов
/ 09 декабря 2018

Если вы знаете, что у вас есть 10 элементов для чтения, это можно сделать немного проще, например:

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

procedure Hello is
   A: array (1..10) of Integer;
begin
   for V of A loop
      Get(V);
   end loop;
   for I in A'Range loop
      Put(I, 5);
      Put(": ");
      Put(A(I), 5);
      New_Line;
   end loop;
end Hello;

Если вы на самом деле не знаете, сколько элементов нужно прочитать заранее, пожалуйста,обновить вопрос.

0 голосов
/ 30 декабря 2018

Несмотря на то, что на этот вопрос уже был дан ответ, я хотел бы добавить пару улучшений к ответу Джере.

Это скорее похоже на Ada, чтобы завершить рекурсию, используя End_Of_File, а не исключение.Кроме того, это делает программу более понятной.

Кроме того, использование рекурсии хвостового вызова вместо обычной рекурсии позволяет компилятору выполнить некоторую оптимизацию.

function Get_Ints(input : in File_Type) return Integer_Array is
    function Get_Ints_Rec(accumulator : in Integer_Array) return Integer_Array is
        value : Integer;
    begin
        if End_Of_File(input) then
            return accumulator;
        else
            begin
               Get(input, value);
            exception
               when Data_Error => -- problem when reading
                  if not End_Of_Line(input) then
                     Skip_Line(input);
                  end if;
                  return Get_Ints_Rec(acc);
            end;
            return Get_Ints_Rec(accumulator & (1 => value));
        end if;
    end Get_Ints_Rec;

    acc : constant Integer_Array(1 .. 0) := (others => 0);
begin
    return Get_Ints_Rec(acc);
end Get_Ints;
0 голосов
/ 08 декабря 2018

Вы можете использовать Get_Line, чтобы получить всю строку в виде строки, а затем Ada.Integer_Text_IO для анализа строки:

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

procedure Hello is
    Line : String := Get_Line;
    Value : Integer;
    Last : Positive := 1;
begin

    while Last < Line'Last loop
        Get(Line(Last..Line'Last),Value,Last);
        Put_Line(Value'Image);  -- Save the value to an array here instead
        Last := Last + 1;    -- Needed to move to the next part of the string
    end loop;

end Hello;

После этого вы можете загрузить значения в массив в цикле или, тем не менее,Вам нравится.

Пример вывода:

$gnatmake -o hello *.adb
gcc -c hello.adb
gnatbind -x hello.ali
gnatlink hello.ali -o hello
$hello
 0
 0
 0
 1
 1
 1
-1
-1
-1
 1

РЕДАКТИРОВАТЬ: Добавление рекурсивной опции, которая является более общей.Это прочитает строку из STDIN и рекурсивно объединит значения в массив.Для этого он использует вторичный стек в GNAT.

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_Io;

procedure Hello is

    -- Need an array return type
    type Integer_Array is array (Positive range <>) of Integer;

    -- Recursive function
    function Get_Ints return Integer_Array is

        Value : Integer;

    begin
        -- Read from STDIN using Integer_Text_IO;
        Get(Value);

        -- Concatinate recursively
        return Integer_Array'(1 => Value) & Get_Ints;

    exception
        -- I found different exceptions with different versions
        -- of GNAT, so using "others" to cover all versions
        when others => 
            -- Using Ada2012 syntax here.  If not using Ada2012
            -- then just declare the Empty variable somewhere
            -- and then return it here
            return Empty : Integer_Array(1..0);

    end Get_Ints;

    Result : Integer_Array := Get_Ints;

begin
  Put_Line("Hello, world!");
  Put_Line(Integer'Image(Result'Length));
  for E of Result loop
    Put(Integer'Image(E) & " ");
  end loop;
end Hello;
...