我有以下代码片段
with GNAT.Command_Line; use GNAT.Command_Line;
with GNAT.Strings; use GNAT.Strings;
....
Define_Switch
(Config => Config, Output => File_Name'Access,
Long_Switch => "--file=", Switch => "-f=",
Help => "File with Composition");
....
Getopt
Run Code Online (Sandbox Code Playgroud)
通过 Getopt 解析命令行后,我可以访问指向实际文件名的对象,我想将此名称复制到定义为的 Ada.String.Fixed 字符串
File_Name : String(1 .. 256);
Run Code Online (Sandbox Code Playgroud)
我可以从 File_Name'Access 打印到控制台数据
Put_Line(File_Name.all);
Run Code Online (Sandbox Code Playgroud)
我想我应该提供诸如复制操作之类的东西,然后自由访问对象。我该怎么做?
谢谢。亚历克斯
小智 5
我猜代码片段中的 File_Name 定义为“别名 GNAT.Strings.String_Access”。这是一个指向字符串对象的“胖指针”。“Fat”意味着它不仅仅是一个地址,它是字符串索引的范围。Ada 中不使用 C 风格的 Nil 终止符,并且 Nil 是有效字符。
您可以将此字符串对象内的数据复制到另一个进行索引计算的标准 String 对象中,但通常您不能这样做:没有 Nil 终止符,您将需要传递实际数据的长度;目标字符串对象可能小于所需的大小,并且数据将被截断或引发异常;ETC。
有两种正确的方法可以做到这一点。第一个是声明不受约束的字符串对象并为其赋值。
declare
Fixed_File_Name : String := File_Name.all;
begin
Free (File_Name);
Run Code Online (Sandbox Code Playgroud)
或使用可变长度字符串(有界或无界):
declare
Unbounded_File_Name : Ada.Strings.Unbounded.Unbounded_String;
begin
Unbounded_File_Name :=
Ada.Strings.Unbounded.To_Unbounded_String (File_Name.all);
Free (File_Name.all);
Run Code Online (Sandbox Code Playgroud)
使用固定字符串有一个重要的限制:字符串对象必须在对象的声明点准确初始化,并且仅在相应的块/子程序内可用。使用可变长度字符串允许在特定块/子程序的范围之外声明字符串对象。