Bug in GNAT Get(FRom => SomeString, Item => SomeInteger, Last => Last)?

78 Views Asked by At

Get(TheFile, IntValue); works great with strings formatted like 16#12# to read hex values. Shouldn't Get from a string function the same way?

I tried this, but passing 16#12# only yields 16. Pure hex, eg F8 results in an exception

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

procedure hex is
   IntValue  : Integer;
   Last : Positive;
begin
   Put("Enter a hexadecimal string: ");
   Get(HexString);

   -- Convert the hexadecimal string to an integer
   Get(From => HexString, Item => IntValue, Last => Last);

   Put ("The integer value is: ");
   Put (IntValue, Width => 0);
   New_Line;
end hex;

2

There are 2 best solutions below

1
Jim Rogers On

The Ada Language Reference Manual states:

procedure Get(From : in String; Item : out Num; Last : out Positive);

Reads an integer value from the beginning of the given string, following the same rules as the Get procedure that reads an integer value from a file, but treating the end of the string as a file terminator. Returns, in the parameter Item, the value of type Num that corresponds to the sequence input. Returns in Last the index value such that From(Last) is the last character read.

The exception Data_Error is propagated if the sequence input does not have the required syntax or if the value obtained is not of the subtype Num.

The explanation of reading a value from a file is

procedure Get(File : in File_Type; Item : out Num; Width : in Field := 0);
procedure Get(Item : out Num; Width : in Field := 0);

If the value of the parameter Width is zero, 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. If a nonzero value of Width is supplied, then exactly Width characters are input, or the characters (possibly none) up to a line terminator, whichever comes first; any skipped leading blanks are included in the count.

The get function works correctly. If you want to convert a string containing an Ada hex value such as 16#12# you should use the 'Value attribute.

with Ada.Text_IO; use Ada.Text_IO;

procedure convert_hex is
   Num : Integer := Integer'Value ("16#12#");
begin
   Put_Line (Num'Image);
end convert_hex;
3
Simon Wright On

Well, that can’t be the code you ran, because you haven’t declared HexString. Also, what’s that Get?

This works as you wanted:

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

procedure hex is
   IntValue  : Integer;
   HexString : String (1 .. 16);
   Last : Natural;
begin
   Put("Enter a hexadecimal string: ");
   Get_Line(HexString, Last => Last);

   -- Convert the hexadecimal string to an integer
   Get(From => HexString (1 .. Last), Item => IntValue, Last => Last);

   Put ("The integer value is: ");
   Put (IntValue, Width => 0);
   New_Line;
end hex;