Reputation: 21
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;
Upvotes: 2
Views: 1917
Reputation: 205885
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;
...
Upvotes: 1
Reputation: 8522
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.
Upvotes: 1
Reputation: 44824
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.
Upvotes: 3