Не могу создать файл в Аде 95 - PullRequest
2 голосов
/ 12 марта 2010

Я пытаюсь следовать стандартной ссылке для открытия файлов, но сталкиваюсь с ограничением_строчки в строке, когда вызываю Ada.Text_IO.Create (). Там написано "проверка диапазона не удалась". Любая помощь приветствуется, вот код:

WITH Ada.Text_IO;
WITH Ada.Integer_Text_IO;
USE Ada.Text_IO;
USE Ada.Integer_Text_IO;

PROCEDURE FileManip IS

   --Variables
   Start_Int : Integer;
   Stop_Int : Integer;
   Max_Length : Integer;

   --Output File
   MaxName : CONSTANT Positive := 80;
   SUBTYPE NameRange IS Positive RANGE 1..MaxName;

   OutFileName : String(NameRange) := (OTHERS => '#');
   OutNameLength : NameRange;
   OutData : File_Type;

   --Array
   TYPE Chain_Array IS ARRAY(1..500) OF Integer;
   Sum : Integer := 1;
BEGIN

--Inputs
   Ada.Text_IO.Put(Item => "Enter a starting Integer: ");
   Ada.Integer_Text_IO.Get(Item => Start_Int);
   Ada.Text_IO.New_Line;
   Ada.Text_IO.Put(Item => "Enter a stopping Integer: ");
   Ada.Integer_Text_IO.Get(Item => Stop_Int);
   Ada.Text_IO.New_Line;
   Ada.Text_IO.Put(Item => "Enter a Maximum Length to search: ");
   Ada.Integer_Text_IO.Get(Item => Max_Length);
   Ada.Text_IO.New_Line;
   Ada.Text_IO.Put(Item => "Enter a output file name > ");
   Ada.Text_IO.Get_Line(
      Item => OutFileName,
      Last => OutNameLength);
   Ada.Text_IO.Create(
      File => OutData,
      Mode => Ada.Text_IO.Out_File,
      Name => OutFileName(1..OutNameLength));
   Ada.Text_IO.New_Line;

Ответы [ 3 ]

3 голосов
/ 12 марта 2010

Скорее всего, проблема не в create, а в проверке диапазона массива OutFileName(1..OutNameLength).

Чтобы это произошло, либо 1, либо OutNameLength должны выходить за пределы диапазона, указанного для OutFileName. Поскольку это было определено как RANGE 1..MaxName (через NameRange), мы знаем, что это не 1, поэтому виновник должен быть OutNameLength.

Оглядываясь вокруг, похоже, что вы получаете это значение из Last параметра Get_Line. Есть одна ситуация, когда вы можете получить 0 из этого параметра: когда вы читаете пустую строку. Так что я думаю, это то, что происходит.

1 голос
/ 12 марта 2010

Тангенциально связанные ...

Обычная практика получения интерактивного ввода - избегать использования "Integer_Text_IO" и связанных пакетов для Gets, вместо этого используйте Get_Line и затем выполняйте преобразование. E.g.:

   S : String(1..200);
   L : Natural;

   ...

   Ada.Text_IO.Put(Item => "Enter a starting Integer: ");
   Ada.Text_IO.Get_Line(Item => S, Last => L);
   Start_Int := Integer'Value(S(1..L));

Этот подход облегчает проверку пользователя, вводящего C / R (L = 0), и в то время как числовые процедуры Get читают символы только до тех пор, пока они соответствуют синтаксису числового литерала, до конца В-третьих, захватывая всю строку с помощью Get_Line, вы избегаете необходимости решать проблему конца строки и можете убедиться, что все из того, что было введено, было числовым литералом (перехватывая Исключение Constraint_Error, если оно возникает при оценке атрибута «Значение».

И хотя это было больше проблемой с более ранними компиляторами Ada, процедуры Get не всегда работали одинаково на разных платформах из-за различных системных соглашений для обозначения конца строки, конца файла и т. Д. Однако Get_Line, в значительной степени работали одинаково на всех платформах, и поэтому это и последующее преобразование строки-> число были широко рекомендуемой практикой.

1 голос
/ 12 марта 2010

Для каждого прочитанного Integer Ada.Integer_Text_IO.Get использует ширину по умолчанию, равную нулю, поэтому "пропускает все начальные пробелы, ограничители строки или терминаторы страницы, а затем читает знак плюс, если он есть ( только тип со знаком) знак минус, если имеется, затем считывает максимально длинную последовательность символов, соответствующую синтаксису числового литерала без точки. " Последующий Ada.Text_IO.New_Line оставляет там терминатор строки для Ada.Text_IO.Get_Line, чтобы отключиться и ноль не в пределах NameRange. Вместо этого используйте Ada.Text_IO.Skip_Line. Например,

Ada.Text_IO.Put(Item => "Enter a starting Integer: ");
Ada.Integer_Text_IO.Get(Item => Start_Int);
Ada.Text_IO.Skip_Line;
Ada.Text_IO.Put(Item => "Enter a stopping Integer: ");
Ada.Integer_Text_IO.Get(Item => Stop_Int);
Ada.Text_IO.Skip_Line;
Ada.Text_IO.Put(Item => "Enter a Maximum Length to search: ");
Ada.Integer_Text_IO.Get(Item => Max_Length);
Ada.Text_IO.Skip_Line;
...
...