4

我有使用 GNAT - GPS 完美运行和编译的 Ada 程序。当我运行它的 exe 文件并提供用户输入而不是说“按任意键继续”时,exe 立即关闭。

我在网上搜索了很多,但我只使用 system('pause'); 找到了与 c/c++/visual studio 控制台窗口相关的信息;或 Console.Readline()。

在 Ada 语言中有没有办法解决这个问题?

4

3 回答 3

6

除了使用Get_Lineor Get,您还可以Get_ImmediateAda.Text_IO包中使用。不同之处在于Get_LineandGet将继续读取用户输入直到<Enter>被击中,而Get_Immediate当标准输入连接到交互式设备(例如键盘)时,只会阻塞直到按下单个键。

这是一个例子:

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;

笔记

  • 您应该在交互式终端(Bash、PowerShell 等)中运行该程序以实际查看Get_Immediate. 当您从 GPS 中运行程序时,您仍然必须按 Enter 键才能真正退出程序。

  • 这可能是太多的细节,但我认为Get仍然等待<Enter>被按下,因为它使用fgetcC 标准库 (libc) 的底层(见这里这里)。该函数fgetc从 C 流中读取。C 流最初是为交互式设备(source)进行行缓冲的。

于 2019-05-28T19:45:13.633 回答
3

@DeeDee 的答案更便携,只有 Ada 和更可取的方法,所以我的答案是如果你正在寻找一种“windows”的方式来做到这一点。

我认为它有一个链接器选项,但我找不到它。一种更手动的方法是从 C 中绑定 system() 命令并给它一个“暂停”命令并将其放在程序的末尾:

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;

我知道你已经提到过暂停,但只是想展示一个例子。

于 2019-05-28T21:52:46.493 回答
1

你可以使用同样的方式Console.Readline(),你可以Get_Line从包Ada.Text_IO中使用。在这种情况下,您必须将结果放入String您不会使用的 a 中。

于 2019-05-28T18:41:24.523 回答