comp.lang.ada
 help / color / mirror / Atom feed
* Get_Line skip input
@ 2021-08-26  5:36 Richard Iswara
  2021-08-26  7:56 ` Niklas Holsti
  2021-08-26  9:09 ` Jeffrey R. Carter
  0 siblings, 2 replies; 4+ messages in thread
From: Richard Iswara @ 2021-08-26  5:36 UTC (permalink / raw)


Why do Get_Line skipped the input? I have the following code:

    -- late declaration of Key words string array
    declare
       type Kw_Array is array (1 .. Kw_Numbers) of String (1 .. 10);
       Key_Words : Kw_Array;
       type W_Len_Array is array (1 .. Kw_Numbers) of Natural;
       W_Len, Multiplier : W_Len_Array;

    begin
       Ada.Text_IO.Put_Line ("Enter keywords less than 10 characters.");
       for i in 1 .. Kw_Numbers loop
          Ada.Text_IO.Put ("Keywords number ");
          Ada.Integer_Text_IO.Put (i, 1);
          Ada.Text_IO.Put (" = ");
+         Ada.Text_IO.Get_Line (Key_Words (i), W_Len (i));
 >         Ada.Text_IO.Put("Enter multiplier for keyword ");
 >         Ada.Integer_Text_IO.Get(Multiplier(i),1);
          Ada.Text_IO.New_Line;
       end loop;
    end;

Before I put the two lines marked above, the executable only skipped the 
first instance of keyword entry.
After I put those two lines, the executable completely skipped the 
Get_Line part.
So on the terminal it shows like this:
Keywords number 1 =  Enter Multiplier for keyword <here cursor wait for 
entry>
Keywords number 2 =  Enter Multiplier for keyword <here cursor wait for 
entry>

If I modifies the line marked + into Get (Key_Words (i) (1..W_Len(i))) 
the compiler complain I did not assign W_Len. Most likely I get the 
syntax incorrect.

What do I do wrong on the original code?

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Get_Line skip input
  2021-08-26  5:36 Get_Line skip input Richard Iswara
@ 2021-08-26  7:56 ` Niklas Holsti
  2021-08-26  9:09 ` Jeffrey R. Carter
  1 sibling, 0 replies; 4+ messages in thread
From: Niklas Holsti @ 2021-08-26  7:56 UTC (permalink / raw)


On 2021-08-26 8:36, Richard Iswara wrote:
> Why do Get_Line skipped the input? I have the following code:
> 
>     -- late declaration of Key words string array
>     declare
>        type Kw_Array is array (1 .. Kw_Numbers) of String (1 .. 10);
>        Key_Words : Kw_Array;
>        type W_Len_Array is array (1 .. Kw_Numbers) of Natural;
>        W_Len, Multiplier : W_Len_Array;
> 
>     begin
>        Ada.Text_IO.Put_Line ("Enter keywords less than 10 characters.");
>        for i in 1 .. Kw_Numbers loop
>           Ada.Text_IO.Put ("Keywords number ");
>           Ada.Integer_Text_IO.Put (i, 1);
>           Ada.Text_IO.Put (" = ");
> +         Ada.Text_IO.Get_Line (Key_Words (i), W_Len (i));
>  >         Ada.Text_IO.Put("Enter multiplier for keyword ");
>  >         Ada.Integer_Text_IO.Get(Multiplier(i),1);


Integer_Text_IO.Get does not read the /whole/ line that contains the 
multiplier -- it only reads the multiplier, but not the "end of line".
Insert this to skip (ignore) the rest of that input line and advance to 
the start of the next input line (which will hold the next keyword):

             Ada.Text_IO.Skip_Line;

>           Ada.Text_IO.New_Line;
>        end loop;
>     end;


As it was, because Integer_Text_IO.Get left the input pointer on the 
multiplier line, the next Get_Line read an empty next keyword (or 
whatever you typed on the multiplier line /after/ the multiplier 
digits), without needing more user input. Skip_Line should correct that.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Get_Line skip input
  2021-08-26  5:36 Get_Line skip input Richard Iswara
  2021-08-26  7:56 ` Niklas Holsti
@ 2021-08-26  9:09 ` Jeffrey R. Carter
  2021-08-27  2:55   ` Richard Iswara
  1 sibling, 1 reply; 4+ messages in thread
From: Jeffrey R. Carter @ 2021-08-26  9:09 UTC (permalink / raw)


On 8/26/21 7:36 AM, Richard Iswara wrote:
> 
> So on the terminal it shows like this:
> Keywords number 1 =  Enter Multiplier for keyword <here cursor wait for entry>
> Keywords number 2 =  Enter Multiplier for keyword <here cursor wait for entry>

I set Kw_Numbers to 3 and added an output loop after the input loop:

    for I in Key_Words'Range loop
       Ada.Text_IO.Put_Line (Item => I'Image & ' ' &
                                     Key_Words (I) (1 .. W_Len (I) ) &
                                     Multiplier (I)'Image);
    end loop;

I am unable to duplicate this behavior:

~/Code$ ./kw_test
Enter keywords less than 10 characters.
Keywords number 1 = one
Enter multiplier for keyword 7

Keywords number 2 = Enter multiplier for keyword 6

Keywords number 3 = Enter multiplier for keyword 3

  1 one 7
  2  6
  3  3

As Holsti explained, this behavior is due to Ada.Integer_Text_IO.Get behaving as 
specified, leaving the rest of the line available to Get_Line:

~/Code$ ./kw_test
Enter keywords less than 10 characters.
Keywords number 1 = one
Enter multiplier for keyword 7

Keywords number 2 = Enter multiplier for keyword 6

Keywords number 3 = Enter multiplier for keyword 3

  1 one 7
  2  6
  3  3
~/Code$ ./kw_test
Enter keywords less than 10 characters.
Keywords number 1 = one
Enter multiplier for keyword 7two

Keywords number 2 = Enter multiplier for keyword 6three

Keywords number 3 = Enter multiplier for keyword 3

  1 one 7
  2 two 6
  3 three 3

In general, I recommend obtaining a complete line and parsing it, rather than 
inputting values with Get:

Get_Mult : loop
    Ada.Text_IO.Put (Item => "Enter multiplier for keyword ");

    One_Mult : declare
       Line : constant String := Ada.Text_IO.Get_Line;
    begin -- One_Mult
       Multiplier (I) := Integer'Value (Line);

       exit Get_Mult;
    exception -- One_Mult
    when others =>
       Ada.Text_IO.Put_Line (Item => "Enter an non-negative integer");
    end One_Mult;
end loop Get_Mult;

In general such code has to handle errors in the input. Users will input key 
words > the specified max and non-numeric multipliers. Error handling is 
simplified if one obtains complete lines (using the Get_Line function) and deals 
with them.

Back in the Good Old Days (TM), I started off using FORTRAN 66 (it was always 
written FORTRAN because the keypunches only had capital letters), where the only 
data structure was the array. Things that would be an array of records in a 
decent language were represented as groups of parallel arrays. That seems to be 
what you're doing here.

subtype KW_Name_Length is Integer range 0 .. 10;

type Key_Word_Info (Length : KW_Name_Length := 0) is record
    Name : String (1 .. Length);
    Multiplier : Natural;
end record;

Num_KW : constant := 3;

type KW_List is array (1 .. Num_KW) of Key_Word_Info;

Key_Word : KW_List;

-- 
Jeff Carter
"Why don't you bore a hole in yourself and let the sap run out?"
Horse Feathers
49

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Get_Line skip input
  2021-08-26  9:09 ` Jeffrey R. Carter
@ 2021-08-27  2:55   ` Richard Iswara
  0 siblings, 0 replies; 4+ messages in thread
From: Richard Iswara @ 2021-08-27  2:55 UTC (permalink / raw)


On 26/08/2021 16.09, Jeffrey R. Carter wrote:
> On 8/26/21 7:36 AM, Richard Iswara wrote:
>>
>> So on the terminal it shows like this:
>> Keywords number 1 =  Enter Multiplier for keyword <here cursor wait 
>> for entry>
>> Keywords number 2 =  Enter Multiplier for keyword <here cursor wait 
>> for entry>
> 
> I set Kw_Numbers to 3 and added an output loop after the input loop:
> 
>     for I in Key_Words'Range loop
>        Ada.Text_IO.Put_Line (Item => I'Image & ' ' &
>                                      Key_Words (I) (1 .. W_Len (I) ) &
>                                      Multiplier (I)'Image);
>     end loop;
> 
> I am unable to duplicate this behavior:
> 
> ~/Code$ ./kw_test
> Enter keywords less than 10 characters.
> Keywords number 1 = one
> Enter multiplier for keyword 7
> 
> Keywords number 2 = Enter multiplier for keyword 6
> 
> Keywords number 3 = Enter multiplier for keyword 3
> 
>   1 one 7
>   2  6
>   3  3
> 
> As Holsti explained, this behavior is due to Ada.Integer_Text_IO.Get 
> behaving as specified, leaving the rest of the line available to Get_Line:
> 
> ~/Code$ ./kw_test
> Enter keywords less than 10 characters.
> Keywords number 1 = one
> Enter multiplier for keyword 7
> 
> Keywords number 2 = Enter multiplier for keyword 6
> 
> Keywords number 3 = Enter multiplier for keyword 3
> 
>   1 one 7
>   2  6
>   3  3
> ~/Code$ ./kw_test
> Enter keywords less than 10 characters.
> Keywords number 1 = one
> Enter multiplier for keyword 7two
> 
> Keywords number 2 = Enter multiplier for keyword 6three
> 
> Keywords number 3 = Enter multiplier for keyword 3
> 
>   1 one 7
>   2 two 6
>   3 three 3
> 
> In general, I recommend obtaining a complete line and parsing it, rather 
> than inputting values with Get:
> 
> Get_Mult : loop
>     Ada.Text_IO.Put (Item => "Enter multiplier for keyword ");
> 
>     One_Mult : declare
>        Line : constant String := Ada.Text_IO.Get_Line;
>     begin -- One_Mult
>        Multiplier (I) := Integer'Value (Line);
> 
>        exit Get_Mult;
>     exception -- One_Mult
>     when others =>
>        Ada.Text_IO.Put_Line (Item => "Enter an non-negative integer");
>     end One_Mult;
> end loop Get_Mult;
> 
> In general such code has to handle errors in the input. Users will input 
> key words > the specified max and non-numeric multipliers. Error 
> handling is simplified if one obtains complete lines (using the Get_Line 
> function) and deals with them.
> 
> Back in the Good Old Days (TM), I started off using FORTRAN 66 (it was 
> always written FORTRAN because the keypunches only had capital letters), 
> where the only data structure was the array. Things that would be an 
> array of records in a decent language were represented as groups of 
> parallel arrays. That seems to be what you're doing here.
> 
> subtype KW_Name_Length is Integer range 0 .. 10;
> 
> type Key_Word_Info (Length : KW_Name_Length := 0) is record
>     Name : String (1 .. Length);
>     Multiplier : Natural;
> end record;
> 
> Num_KW : constant := 3;
> 
> type KW_List is array (1 .. Num_KW) of Key_Word_Info;
> 
> Key_Word : KW_List;
> 
Thank you Niklas and Jeffrey for the explanation and the better way to 
do an input message.
Regards,
Richard.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-08-27  2:55 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-26  5:36 Get_Line skip input Richard Iswara
2021-08-26  7:56 ` Niklas Holsti
2021-08-26  9:09 ` Jeffrey R. Carter
2021-08-27  2:55   ` Richard Iswara

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox