无法在 Ada 95 中创建文件

发布于 2024-08-25 09:03:58 字数 1372 浏览 7 评论 0原文

我试图遵循打开文件的标准参考,但当我调用 Ada.Text_IO.Create() 时,在该行遇到了constraint_error。它说“范围检查失败”。感谢任何帮助,这是代码:

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;

I'm trying to follow a standard reference for opening files but running into a constraint_error at the line when I call Ada.Text_IO.Create(). It says "range check failed". Any help appreciated, here's the code:

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

断爱 2024-09-01 09:04:00

切线相关...

获取交互式输入的常见做法是避免使用“Integer_Text_IO”和相关包进行Gets,而是使用Get_Line,然后进行转换。例如:

   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 抓取整行,您可以避免处理行尾问题,并且可以确保输入的所有都是数字文字(通过捕获如果在评估“Value 属性”时引发 Constraint_Error 异常)。

虽然早期的 Ada 编译器存在更多问题,但由于不同系统指定行尾、文件尾等的约定,Get 过程在不同平台上的工作方式并不总是相同。不过,Get_Line 几乎可以工作在所有平台上都是相同的,因此它和随后的字符串->数字转换是广泛推荐的做法。

Tangentially related...

A common practice for acquiring interactive input is to avoid using the "Integer_Text_IO" and related packages for Gets, and instead use Get_Line and then do a conversion. 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));

This approach makes it easier to check for a user entering a C/R (L = 0), and while the numeric Get procedures only read characters so long as they conform to the syntax of a numeric literal, up to the end-of-line, by grabbing the whole line with Get_Line, you avoid having to deal with the end-of-line issue and can make sure that all of what was entered was a numeric literal (by catching the Constraint_Error exception if one is raised when evaluating the 'Value attribute).

And although it was more of a problem with earlier Ada compilers, the Get procedures didn't always work identically on different platforms due to different systems' conventions for designating end of line, end of file, etc. Get_Line, though, pretty much worked the same across all platforms, and so it and a subsequent string->numeric conversion was a widely recommended practice.

国际总奸 2024-09-01 09:04:00

对于您读取的每个 IntegerAda.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;
...

For each Integer you read, Ada.Integer_Text_IO.Get uses the default Width of zero, so it "skips any leading blanks, line terminators, or page terminators, then reads a plus sign if present or (for a signed type only) a minus sign if present, then reads the longest possible sequence of characters matching the syntax of a numeric literal without a point." A subsequent Ada.Text_IO.New_Line leaves the line terminator there for Ada.Text_IO.Get_Line to trip over, and zero is not within NameRange. Instead use Ada.Text_IO.Skip_Line. For example,

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;
...
等待我真够勒 2024-09-01 09:03:59

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

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

环顾四周,您似乎从 Get_LineLast 参数中获取了该值。在一种情况下,您可以从该参数中获取 0:当您读取空行时。所以我的猜测是,这就是正在发生的事情。

Likely it isn't the create that is giving you that problem, but an array range check on OutFileName(1..OutNameLength).

For that to happen, either 1 or OutNameLength would need to be out of the range specified for OutFileName. Since that was defined as RANGE 1..MaxName (via NameRange), we know it isn't the 1, so the culprit must be OutNameLength.

Looking around, it looks like you get that value from the Last parameter of a Get_Line. There is one situation where you can get a 0 out of that parameter: when you read a blank line. So my guess is that is what is happening.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文