String ada中的文件IO,如何将字符串写入文件?

String ada中的文件IO,如何将字符串写入文件?,string,io,ada,String,Io,Ada,关于将字符串变量写入文件,我有一些问题。 问题是我必须指定该字符串的确切长度。否则,输出文件将只包含一些废弃值。我想知道这是否可以在不需要事先告诉绳子长度的情况下以某种方式解决 我知道我的Get()。然而,我想写我的程序,所以在我开始写输出文件之前,它将首先从输入文件中读取所有数据 with Ada.Text_Io, Ada.Integer_Text_Io; use Ada.Text_Io,Ada.Integer_Text_Io; procedure Uppgift is type

关于将字符串变量写入文件,我有一些问题。 问题是我必须指定该字符串的确切长度。否则,输出文件将只包含一些废弃值。我想知道这是否可以在不需要事先告诉绳子长度的情况下以某种方式解决

我知道我的
Get()。然而,我想写我的程序,所以在我开始写输出文件之前,它将首先从输入文件中读取所有数据

with  Ada.Text_Io, Ada.Integer_Text_Io;
use Ada.Text_Io,Ada.Integer_Text_Io;

procedure Uppgift is

   type Bil_Register is
      record
     Namn    : String(1..50);
     Adress  : String(1..50);
     Post    : String(1..50);
     Reg     : String(1..6);
      end record;   

   Infil  : File_Type;
   Utfil        : File_Type;
   L, I : Integer;

   Br : Bil_Register;

   procedure Get(F : in out File_Type; Br : out Bil_Register) is
      Length : Integer;
   begin
      Get_Line(F, Br.Namn, Length);      
   end;

begin

   Open(Infil, In_File, "register.txt");
   Create(Utfil, Out_File, "test.txt");

   Get(Infil, Br);
   Put_Line(Utfil, Br.Namn);

   Close(Infil);
   Close(Utfil);

end Uppgift;
-

编辑(2011.08.20)


这似乎只是基于Unix的操作系统的一个问题。使用Windows时,当您将字符串打印到文件或屏幕时,您不必绝对控制字符串大小。嗯,字符串有效部分的长度必须在某个地方进行跟踪

您可以将每个记录字符串字段的有效长度作为单独的字段进行维护:

Namn        : String (1..50);
Namn_Length : Natural;
您可以定义自己的变量字符串类型包,或者使用预先存在的包,例如。例如

您可以对字段和变量使用无界_字符串:

Namn : Unbounded_String;
对于I/O:


如果您不想使用无界_IO包,请使用to_String和to_Unbounded_String在无界_字符串值和通过文本_IO读写的字符串之间来回转换。

我个人只想使用无界_String,正如Marc所建议的那样,但如果您想避免这种情况,可以这样做:

with Ada.Text_IO;
with Ada.Containers.Indefinite_Doubly_Linked_Lists;

use Ada.Text_IO;
use Ada.Containers;

procedure Uppgift is

   type Bil_Register (Namn_Length : Natural) is
      record
         Namn    : String (1 .. Namn_Length);
         --  Other components removed for brevity.
      end record;   

   package BR_Container is new Indefinite_Doubly_Linked_Lists (Bil_Register);
   use BR_Container;

   BR_List        : BR_Container.List;
   BR_List_Cursor : BR_Container.Cursor;
   Buffer         : String (1 .. 100);
   Length         : Natural;
   Register_File  : File_Type;
   Test_File      : File_Type;

begin

   --  First we read the contents of register.txt and add all the data to
   --  our list of Bil_Register objects.
   Open (File => Register_File,
         Mode => In_File,
         Name => "register.txt");

   while not End_Of_File (File => Register_File) loop
      Get_Line (File => Register_File,
                Item => Buffer,
                Last => Length);
      declare
         BR : Bil_Register 
           (Namn_Length => Length);
      begin
         BR.Namn := Buffer (1 .. Length);
         BR_List.Append (New_Item => BR);
      end;
   end loop;

   Close (File => Register_File);

   --  Then we output the contents of our list of Bil_Register objects to 
   --  test.txt
   Create (File => Test_File,
           Mode => Out_File,
           Name => "test.txt");

   BR_List_Cursor := BR_List.First;
   while Has_Element (Position => BR_List_Cursor) loop
      Put_Line (File => Test_File,
                Item => Element (Position => BR_List_Cursor).Namn);
      Next (Position => BR_List_Cursor);
   end loop;

   Close (File => Test_File); 

end Uppgift;
我将读写分为两个部分,因为你说:

…执行输入文件中的所有读取操作 首先,在我开始给客户写信之前 出档

显然,使用这种方法,必须适当调整缓冲区变量的大小。但实际上,与仅使用无界_字符串相比,它相当笨拙。我要说的是,除非你有一些非常具体的关注点或要求,否则无界字符串可能是一条出路。它将大大简化事情


祝你好运o)

通常,您无需在Ada中使用特殊的“长度”变量,就可以摆脱此问题。不幸的是,这是一个很难实现的案例

然而,在这种情况下,有一个技巧可以让你做到这一点。如果您不介意一点递归,或者不希望字符串非常长,或者不太关心执行速度(您正在执行I/O,所以速度会很慢)。如果你觉得这没问题,试试看

现在,您可以将代码更改为:

begin

   Open(Infil, In_File, "register.txt");
   Create(Utfil, Out_File, "test.txt");

   Put_Line(Utfil, Next_Line (Infil));

   Close(Infil);
   Close(Utfil);

end Uppgift;

您是否有使用无界_字符串进行文件I/O的示例?我不能让它工作。我编辑了一个快速演示我扔在一起的问题。请注意,您正在处理的文件是Ada.Text\u IO的文件类型。我试图使用无界字符串,但我收到一些投诉,说我试图使用它,但它收到的是正常字符串。。您没有一个简单的示例,如何使用它进行文件读/写?
with Ada.Text_IO;
with Ada.Containers.Indefinite_Doubly_Linked_Lists;

use Ada.Text_IO;
use Ada.Containers;

procedure Uppgift is

   type Bil_Register (Namn_Length : Natural) is
      record
         Namn    : String (1 .. Namn_Length);
         --  Other components removed for brevity.
      end record;   

   package BR_Container is new Indefinite_Doubly_Linked_Lists (Bil_Register);
   use BR_Container;

   BR_List        : BR_Container.List;
   BR_List_Cursor : BR_Container.Cursor;
   Buffer         : String (1 .. 100);
   Length         : Natural;
   Register_File  : File_Type;
   Test_File      : File_Type;

begin

   --  First we read the contents of register.txt and add all the data to
   --  our list of Bil_Register objects.
   Open (File => Register_File,
         Mode => In_File,
         Name => "register.txt");

   while not End_Of_File (File => Register_File) loop
      Get_Line (File => Register_File,
                Item => Buffer,
                Last => Length);
      declare
         BR : Bil_Register 
           (Namn_Length => Length);
      begin
         BR.Namn := Buffer (1 .. Length);
         BR_List.Append (New_Item => BR);
      end;
   end loop;

   Close (File => Register_File);

   --  Then we output the contents of our list of Bil_Register objects to 
   --  test.txt
   Create (File => Test_File,
           Mode => Out_File,
           Name => "test.txt");

   BR_List_Cursor := BR_List.First;
   while Has_Element (Position => BR_List_Cursor) loop
      Put_Line (File => Test_File,
                Item => Element (Position => BR_List_Cursor).Namn);
      Next (Position => BR_List_Cursor);
   end loop;

   Close (File => Test_File); 

end Uppgift;
function Next_Line(File : in Ada.Text_IO.File_Type :=
   Ada.Text_Io.Standard_Input) return String is
   Answer : String(1..256);
   Last   : Natural;
begin
   Ada.Text_IO.Get_Line(File => File,
      Item => Answer,
      Last => Last);
   if Last = Answer'Last then
      return Answer & Next_Line(File);
   else
      return Answer(1..Last);
   end if;
end Next_Line;
begin

   Open(Infil, In_File, "register.txt");
   Create(Utfil, Out_File, "test.txt");

   Put_Line(Utfil, Next_Line (Infil));

   Close(Infil);
   Close(Utfil);

end Uppgift;