【问题标题】:Read input from a pipe in Ada从 Ada 中的管道读取输入
【发布时间】:2018-01-10 12:28:00
【问题描述】:

我有一段代码(见下文)从作为命令行参数给出的文件中读取数据。我想添加对能够从管道读取输入的支持。例如,当前版本将数据读取为main <file_name>,而在cmd1 | main 行也应该可以做一些事情。这是从文件中读取数据的来源:

procedure main is

    File : Ada.Text_IO.File_Type;

begin

   if Ada.Command_Line.Argument_Count /= 1 then

      return;

   else

      Ada.Text_IO.Open (
         File => File,
         Mode => In_File,
         Name => Ada.Command_Line.Argument (1));

      while (not Ada.Text_IO.End_Of_File (File)) loop
         -- Read line using Ada.Text_IO.Get_Line
         -- Process the line
      end loop;

      Ada.Text_IO.Close (File);

end main;

如果我理解正确,管道只是 Ada 中的一种非常规文件类型。但是我该如何处理呢?

【问题讨论】:

  • 有点不清楚你在问什么,但如果你想访问标准 i/O 管道 stdin, stdout, stderr,请查看 Ada.Text_IO.Standard_Output 等文件(同上 Stream_IO 等),例如ada.tips/redirecting-text_io-output-to-a-file.html
  • 我要问的是如何使程序既支持从作为命令行参数提供的文件中读取(已经完成),又在这种使用的情况下从管道中读取输入.你的意思是管道只是一个stdin

标签: file pipe ada


【解决方案1】:

这些似乎都不能真正回答您的问题。管道只是让另一个程序的标准输出成为你程序的标准输入,所以你通过读取 Standard_Input 来读取管道。

Current_Input 函数返回一个 File_Type。它最初返回 Standard_Input,但调用 Set_Input 会将其更改为返回您传递给 Set_Input 的任何内容。因此,如果没有给出文件,如何从 Standard_Input 读取,如果有,则从给定文件读取的粗略概述如下:

File : File_Type;

if Argument_Count > 0 then
   Open (File => File, Name => Argument (1), Mode => In_File);
   Set_Input (File => File);
end if;

All_Lines : loop
   exit All_Lines when End_Of_File (Current_Input);

   Process (Line => Get_Line (Current_Input) );
end loop All_Lines;

【讨论】:

    【解决方案2】:

    您甚至无需创建文件即可从管道读取数据。

    只是

    with Ada.Text_IO;
    procedure main is
    
        begin
    
          loop
            exit when Ada.Text_IO.End_Of_File;
            Ada.Text_IO.Put_Line("Echo" &Ada.Text_IO.Get_Line);
          end loop;
    end main;
    

    然后type ..\src\main.adb | main.exe 工作。

    【讨论】:

      【解决方案3】:

      引用the ARM...

      库包Text_IO有如下声明:

      ...
      package Ada.Text_IO is
      ...
         -- Control of default input and output files
      
         procedure Set_Input (File : in File_Type);
         procedure Set_Output(File : in File_Type);
         procedure Set_Error (File : in File_Type);
      
         function Standard_Input  return File_Type;
         function Standard_Output return File_Type;
         function Standard_Error  return File_Type;
      
         function Current_Input   return File_Type;
         function Current_Output  return File_Type;
         function Current_Error   return File_Type;
      

      允许您将默认管道stdin, stdout, stderr 作为文件操作;可以作为预先打开的文件(输入和输出管道)或允许您将标准输出重定向到您自己的文件等。

      This example 显示将标准管道之一重定向到文件并将其还原到系统提供的文件。或者,可以调用 File I/O 子程序,并将 File 参数设置为例如Ada.Text_IO.Standard_Output 并且应该像预期的那样简单地工作 - 输出到终端或任何你在命令行上通过管道传递 stdout 的东西。

      如果您正在读取和写入的数据不是文本,Direct_IO, Sequential_IO, Stream_IO 等中应该提供类似的工具。

      Timur 的回答表明您可以直接对这些管道进行读写;这个答案的方法允许您将标准管道与其他文件统一处理,以便您可以通过文件或具有相同代码的管道进行 I/O。例如,如果提供了命令行文件名,请使用该文件,否则将您的文件指向Standard_Output

      如果您要问命令行cmd1|main|grep "hello" 中发生了什么,是的,cmd1 的输出位于名为stdout(C 语言)或Standard_Output(Ada)的管道上,该管道通过 ( Unix 特定的管道命令)|到您用 Ada 编写的 main 程序的 Standard_Input。反过来,它的Standard_Output 被传送到 grep 的 stdin 中,它会搜索“hello”。

      如果您问的是如何打开和访问命名管道,我怀疑这是特定于操作系统的,并且可能是一个更难的问题。

      (在这种情况下,this Stack Exchange Q&A 可能会有所帮助)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-23
        • 2015-10-08
        • 2014-03-13
        • 2013-11-04
        相关资源
        最近更新 更多