Ada语言-如何存储函数返回的字符串值?

Wos*_*ame 6 string declaration function ada

我正在尝试在Ada 2012中进行一些基本的命令行交互,但是我找不到一种方法来捕获从Ada.Command_Line.Command_Name()函数返回的字符串。

我在网上可以找到的所有示例都只需使用Put()打印字符串,而无需先将其存储在本地变量中。这是我尝试过的错误代码,虽然可以编译,但是CONSTRAINT_ERROR ... length check failed在我尝试将返回String值分配给String变量时抛出了一个错误代码...

with Ada.Command_Line; use Ada.Command_Line;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings; use Ada.Strings;

procedure Command_Line_Test is
  ArgC : Natural := 0;
  InvocationName : String (1 .. 80);
begin
  ArgC := Argument_Count;
  Put ("Number of arguments provided: ");
  Put (ArgC'Image);
  New_Line;

  InvocationName := Command_Name;  --  CONSTRAINT_ERROR here
  Put ("Name that the executable was invoked by: ");
  Put (InvocationName);
  New_Line;

end Command_Line_Test;
Run Code Online (Sandbox Code Playgroud)

我仅以Command_Name为例,但可以想象它是任何其他函数都可以返回字符串(也许在程序生命周期内可能会多次更改的字符串),我们应该如何声明局部变量才能存储返回的字符串串?

Tim*_*dze 9

Ada中的字符串处理与其他编程语言非常不同,当您声明String(1..80)时,它期望函数返回的字符串的长度实际上为1..80,而可执行路径(由Command_Name返回)可能会更短(或更长时间)。

您可能总是会引入新的声明块,并在其中创建一个String变量,如下所示

with Ada.Command_Line; use Ada.Command_Line;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings; use Ada.Strings;

procedure Main is
   ArgC : Natural := 0;

begin
   ArgC := Argument_Count;
   Put ("Number of arguments provided: ");
   Put (ArgC'Image);
   New_Line;
   declare
      InvocationName: String := Command_Name;  --  no more CONSTRAINT_ERROR here
   begin
      Put ("Name that the executable was invoked by: ");
      Put (InvocationName);
      New_Line;
   end;

end Main;
Run Code Online (Sandbox Code Playgroud)

或者您可以使用Ada.Strings.Unbounded包

with Ada.Command_Line; use Ada.Command_Line;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings; use Ada.Strings;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;

procedure Main is
   ArgC : Natural := 0;
   InvocationName : Unbounded_String;
begin
   ArgC := Argument_Count;
   Put ("Number of arguments provided: ");
   Put (ArgC'Image);
   New_Line;

   InvocationName := To_Unbounded_String(Command_Name);  --  no more CONSTRAINT_ERROR here

   Put ("Name that the executable was invoked by: ");
   Put (To_String(InvocationName));
   New_Line;

end Main;
Run Code Online (Sandbox Code Playgroud)


小智 5

同意 Timur,只是不需要将 Invocation_Name 的声明移动到嵌套的声明块中。

你本来可以写的;

   Invocation_Name : String := Command;
Run Code Online (Sandbox Code Playgroud)

它在原始代码中的位置,在过程 Main 的声明中。

或者更好;

   Invocation_Name : constant String := Command;
Run Code Online (Sandbox Code Playgroud)

或者更好的是,完全消除声明并将 Main 的最后 3 行替换为;

   Put_Line ("Name that the executable was invoked by: " & Command);
Run Code Online (Sandbox Code Playgroud)