Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop console window from closing immediately | GNAT - GPS

Tags:

ada

gnat-gps

I have Ada program that runs and compile perfectly using GNAT - GPS. When I run its exe file and provide user input then instead of saying "Press any key to continue", the exe closes immediately.

I have searched for it online alot but i only found info related to c/c++/visual studio console window using system('pause'); OR Console.Readline().

Is there any way around for this in Ada lanaguage?

like image 246
John Bravo Avatar asked Dec 22 '22 23:12

John Bravo


2 Answers

Apart from using Get_Line or Get, you can also use Get_Immediate from the Ada.Text_IO package. The difference is that Get_Line and Get will continue to read user input until <Enter> has been hit, while Get_Immediate will block only until a single key has been pressed when standard input is connected to an interactive device (e.g. a keyboard).

Here's an example:

with Ada.Text_IO; use Ada.Text_IO;

procedure Main is
begin

   --  Do some interesting stuff here...   

   declare
      User_Response : Character;
   begin
      Put_Line ("Press any key to continue...");
      Get_Immediate (User_Response);
   end;

end Main;

NOTES

  • You should run the program in an interactive terminal (Bash, PowerShell, etc.) to actually see the effect of Get_Immediate. When you run the program from within GPS, then you still have to press enter to actually exit the program.

  • This might be too much detail, but I think that Get still waits for <Enter> to be pressed because it uses fgetc from the C standard library (libc) under the hood (see here and here). The function fgetc reads from a C stream. C streams are initially line-buffered for interactive devices (source).

like image 120
DeeDee Avatar answered Mar 03 '23 10:03

DeeDee


The answer from @DeeDee is more portable and only Ada and the preferable way to go, so my answer is just if you are looking for a "windows" way to do it.

I think there is a linker option for it, but I couldn't find it. A more manual way is to bind the system() command from C and give it a "pause" command and place it at the end of your program:

with Ada.Text_IO; use Ada.Text_IO;
with Interfaces.C.Strings;

procedure Main is

   function System(Str : Interfaces.c.strings.chars_ptr) return Interfaces.C.int
      with Import,
      Convention => C,
      External_Name => "system";

   procedure Pause is
      Command : Interfaces.c.Strings.chars_ptr
         := Interfaces.C.Strings.New_String("pause");
      Result  : Interfaces.C.int
         := System(Command);
   begin
      Interfaces.C.Strings.Free(Command);
   end Pause;

begin
   Put_Line("Hello World");
   Pause;
end Main;

I know you mentioned seeing about pause already, but just wanted to show an example.

like image 43
Jere Avatar answered Mar 03 '23 08:03

Jere