支持管道(一个有用的Hello World) 我试图写一个简单的C++程序集合,它遵循基本UNIX哲学: 让每个程序都做好一件事 期望每个程序的输出成为另一个未知程序的输入

支持管道(一个有用的Hello World) 我试图写一个简单的C++程序集合,它遵循基本UNIX哲学: 让每个程序都做好一件事 期望每个程序的输出成为另一个未知程序的输入,c++,unix,command-line,pipe,stdin,C++,Unix,Command Line,Pipe,Stdin,我遇到了一个问题,试图将其中一个的输出作为另一个的输入,而将其中一个的输出作为其自身单独实例的输入。非常简单,我有一个程序add,它接受参数并给出求和结果。我希望能够通过管道将输出传输到另一个add实例 ./add 1 2 | ./add 3 4 这将产生10,但目前产生7 我遇到了两个问题: cin等待来自控制台的用户输入。我不想这样,而且在没有在控制台中查询用户的情况下,无法找到一个简单的示例来演示标准输入流的使用。如果有人知道一个例子,请让我知道 我不知道如何在支持管道的同时使用标准输入

我遇到了一个问题,试图将其中一个的输出作为另一个的输入,而将其中一个的输出作为其自身单独实例的输入。非常简单,我有一个程序add,它接受参数并给出求和结果。我希望能够通过管道将输出传输到另一个add实例

./add 1 2 | ./add 3 4
这将产生10,但目前产生7

我遇到了两个问题:

  • cin等待来自控制台的用户输入。我不想这样,而且在没有在控制台中查询用户的情况下,无法找到一个简单的示例来演示标准输入流的使用。如果有人知道一个例子,请让我知道
  • 我不知道如何在支持管道的同时使用标准输入。目前,它似乎不起作用。如果我发出命令/add12 |/add34,结果是7
  • 相关代码如下:

    add.cpp代码段

    // ... COMMAND LINE PROCESSING ...
        std::vector<double> numbers = multi.getValue(); // using TCLAP for command line parsing
    
        if (numbers.size() > 0)
        {
        double sum = numbers[0];
    
        double arg;
        for (int i=1; i < numbers.size(); i++)
        {
          arg = numbers[i];
    
          sum += arg;
        }
    
        std::cout << sum << std::endl;
      }
      else
      {
          double input;
          // right now this is test code while I try and get standard input streaming working as expected
          while (std::cin)
          {
                std::cin >> input;
    
                std::cout << input << std::endl;
          }
    
        }
    // ... MORE IRRELEVANT CODE ...
    
    /。。。命令行处理。。。
    std::vector number=multi.getValue();//使用TCLAP进行命令行解析
    如果(numbers.size()>0)
    {
    双和=数字[0];
    双精氨酸;
    对于(int i=1;istd::cout您可能会发现一个有用的函数是
    isatty()
    ,它告诉您文件描述符是否连接到交互式会话。您可以这样使用它:

    if (!isatty(fileno(stdin))) {
        while (std::cin) {
            // ...
        }
    }
    

    这将仅尝试从终端读取非交互式输入(意味着stdin从文件或管道重定向)。

    问题可能在于:

    if (numbers.size() > 0)
    
    如果您有任何参数,它会添加它们并忽略所有管道数据。因此当然
    /add 3
    返回3-它有一个参数,因此它会忽略管道数据


    您应该修复代码以添加这两个输入(如果给定了输入)还有参数,不是非此即彼。记住:命令行参数并不排除管道输入。

    我想说最简单的方法是忽略程序中从
    stdin
    读取的内容。相反,只让程序读取参数,并像这样调用它:
    /add 1 2 | xargs./add 3 4


    xargs
    会将第一个
    add
    的输出作为第二个
    add

    的参数这是两个问题,其中一个问题相当模糊(Unix哲学问题)。实际上,你的问题是关于管道的,如果有好的例子。我建议将标题更改为匹配。你写它“returns 3”-这是哪3个?是来自add命令(在管道之前还是第二个add命令的参数之前?啊,很好的回答。这是第二个3。我也发布了./ADD12 |./ADD34,它会产生7。Re:您的更新:现在请参阅@gregHewgill的答案,了解如何确定您的程序是从管道还是从控制台读取。
    if (!isatty(fileno(stdin))) {
        while (std::cin) {
            // ...
        }
    }
    
    if (numbers.size() > 0)