File Can';t在ADA95中创建文件

File Can';t在ADA95中创建文件,file,ada,File,Ada,我试图遵循打开文件的标准引用,但在调用Ada.Text\u 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 : Integ

我试图遵循打开文件的标准引用,但在调用Ada.Text\u 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;

对于您读取的每个
Integer
Ada.Integer\u Text\u IO.Get
使用默认宽度为零,因此随后的
Ada.Text\u IO.New\u Line
会在那里为
Ada.Text\u IO.Get\u 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;
...

切向相关的

获取交互式输入的一种常见做法是避免使用“Integer\u Text\u IO”和Get的相关包,而是使用Get\u行,然后进行转换。例如:

   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_行抓取整行,您不必处理行尾问题,并且可以确保输入的所有内容都是数字文字(通过捕获约束错误异常,如果在计算“Value”属性时引发约束错误异常)


尽管早期的Ada编译器存在更多的问题,但由于系统指定行结束、文件结束等的约定不同,Get过程在不同平台上的工作方式并不完全相同。尽管如此,Get_行在所有平台上的工作方式基本相同,因此,它和随后的字符串->数字转换是一种被广泛推荐的做法。

很可能不是
create
给您带来了这个问题,而是
OutFileName(1..OutNameLength)
上的数组范围检查

要实现这一点,1或OutNameLength都需要超出为OutFileName指定的范围。因为它被定义为
RANGE 1..MaxName
(通过NameRange),我们知道它不是1,所以罪魁祸首一定是
OutNameLength


环顾四周,您似乎从
get\u行
Last
参数中获得了该值。有一种情况下,您可以从该参数中得到一个0:当您读取一个空行时。因此,我的猜测是,这就是正在发生的情况。

Get仅在指定了宽度的非零值(请参阅链接引用)时才会读取“最多一行终止符”。如果Width为零,则默认情况下,Integer_Text_IO.Get“读取与无点数字文本语法匹配的最长字符序列”。感谢您捕捉到这一点;答案已修改。我们可以看到准确的错误消息吗?作为旁白,每个包都有一个use子句,然后写下每个子程序调用的全名。你不必同时做这两件事,尽管在开始时使用全名很好。+1虽然与问题无关,但这是一个更可靠的习惯用法。