Ada input from a terminal

Your description of behavior doesn’t match the code you’re posting.
Are you perhaps running a previous EXE?
Also there’s a lot of questionable things: for example, why are you displaying the input as ‘Between’ while not displaying the input at ‘Input =’, a point after you’ve gotten any input? Why are you simply reiterating the input, but labeling it output?

Why are you importing unused dependences via with/use? Are you importing some other unit which is doing I/O?

With Ada.Text_IO;
procedure test_get_keyboard is
      Use Ada.Text_IO;
Begin
   Put_Line("Input    = ");
   Declare
      Line : string renames Get_Line;
   Begin
      Put_line("Between  = " & Line );
      Put_Line("Length   ="  & Natural'image(Line'Length) & " (Length of Line)");
      Put_Line("Output   = " & Line);
   End;      
End test_get_keyboard;

Try clearing out your project and running the above to see if that comports to what you are trying to do.

I took your code plopped it into a file, compiled it and ran it. For me using msys2 on Windows 11, the code ran as expected: I had to input a number and hit the enter key once to get the output to generate.

output:

$ ./bin/main.exe 
1234 
Input    = 
Between  = 1234
Length   =  Length of In_Line 5
Output   = 1234

If I modify your code to look a bit different:

   procedure test_get_keyboard is
   begin
      Put("Input    = ");
      declare
         In_Line     : string := Get_Line;
      begin
         Put_line("Between  = " & In_Line );
         Put_Line("Length   = " & " Length of In_Line" & natural'image(In_Line'Length));
         Put_Line("Output   = " & In_Line);
      end;
   end test_get_keyboard;

Then it gives a slightly nicer look and feel but still works as expected (I type in a number and hit enter once and it works):

$ ./bin/main.exe 
Input    = 1234
Between  = 1234
Length   =  Length of In_Line 4
Output   = 1234

I never had to hit enter twice. It just worked.

Are you redirecting a file to be the input? Could that be the problem, or am I off base?

(Wondering on your account of having to supply CR and LF. You shouldn’t have to do either if you’re using the keyboard, but if you were feeding it an artisanally handcrafted file, or perhaps a file copied from another operating system, then it would make a little more sense.)

I now have changed my program as suggested. but that did not gave another result. Maybe interesting:

  1. I did use GNAT Studio for editing and “building & running” . That gave the result as can be seen with two times
  2. In ran the same .exe file in MSYS2. In this case only the “Input =” and input can be seen. After 4 times nothing had happened.
  3. I also did run in the Windows Power shell in the administrator version. This has no output at all.
  4. Running the exe file from the Windows Explorer did not react at all as I double clicked .I now the listing as it is along with the result from GNAT Studio.
pragma License(Unrestricted);

with Ada.Text_IO;            use Ada.Text_IO;

procedure test_get_keyboard is

begin
   Put_Line("Input    = ");
declare
   In_Line     : string := Get_Line;
   begin
      Put_line("Between = " & In_Line );
      Put_Line(“Length   = " & " Length of In_Line” & natural’image(In_Line’Length));
      Put_Line("Output   = " & In_Line);
   end;
end test_get_keyboard;

D:\ada\project\Test_Get_Keyboard\test_get_keyboard.exe
Input    =
123abc

Between = 123abc
Length   =  Length of In_Line 6
Output   = 123abc
[2026-03-31 08:15:11] process terminated successfully, elapsed time: 23.36s

To cantanima I used a keyboard as input and not a file. At first I thought something was wrong with the line terminator from the keyboard .

To OneWingedShark I Did use the .exe which produced the output. I Compile with GNAT Studio 26.0 and yes the code does not match the output, that is the problem. You can see the input once the other one is the result of the Get_Line. The problem is just that,you just need two extra enter’s two go on.

Try:

procedure test_get_keyboard is
begin
   Flush( File => Current_Input );
   Put("Input    = ");
   declare
      In_Line : string renames Get_Line;
   begin
      Put_line("Between  = " & In_Line );
      Put_Line("Length   ="  & natural’image(In_Line’Length) & " (In_Line)");
      Put_Line("Output   = " & In_Line);
   end;
end test_get_keyboard;

Thanks for your input. I now got an Error:

raised ADA.IO_EXCEPTIONS.MODE_ERROR : System.File_IO.Check_Write_Status: file not writable
[2026-04-01 12:03:10] process exited with status 1, elapsed time: 00.14s.

I just don’t know what happens. It looks to me that the write status in here can only occur in the Put or Put_Line statements and they were used before without that error.

Oh, right, flush is for output files and I put Current_Input.
I doubt Current_Output would do anything, but you should try it because some of the stuff you’re describing is… odd.

Why? IBM OS/360 access methods could indicate that the last record (end of a data set) has been reached or a tape mark has been reached.

If you can live with a blocking read(2) UNIX system call, returning 0 bytes indicates the end of file condition. If using stdio higher-level abstraction, this is reported by feof(3) being true. Even termios terminal input package has a “clever” way to adhere to this convention - sending the EOF control character flushes the input buffer immediately, which, in case no characters have been sent on a line, causes the receiver to get 0 bytes, which is interpreted as an EOF condition. (Worst case you have to press the EOF character twice, yes, this is inconsistent, but not visible to the receiver at all).

How do you unget EOT? Rewind and reposition the tape? :grinning: Yes, operating systems before UNIX had kind of typed files. There were record files where lines were records and needed no sequences indicating “line end.” LF meant “move the paper one line up” just that.

You cannot read EOL or EOF, there is no such things. UNIX invented substitutes for, which then propagated into physical characters combinations. NUL-terminated strings, how good did they work? MS-DOS even tried to introduce EOF in the files, which everybody ignored. It is an elegant but harmful idea of adding so-called ideals to a type, e.g. of numbers (NaN), characters (EOF, EOL, NUL), pointers (null).

In Ada an application does not need it. Use Get_Line and ignore what happens below. Handle End_Error and it will work with all type of files.

If it hasn’t been obvious by now, UNIX and Ada world have totally different values. I have nothing to add!

sent using imperfect BSD socket interface