【问题标题】:Redirect two separate stdin as input to a program将两个单独的标准输入重定向为程序的输入
【发布时间】:2017-08-28 09:14:02
【问题描述】:

以下示例输出来自stdin 的输入:

#include <iostream>

int main(int argc, char **argv)
{
    std::string s1, s2;
    while (getline(std::cin, s1))
    {
        std::cout << s1 << " 1\n";
    }

    while (getline(std::cin, s2))
    {
        std::cout << s2 << "2\n";
    }
    return 0;
}

我这样运行程序:cat main.cpp | ./main 输出

#include <iostream> 1
 1
int main(int argc, char **argv) 1
{ 1
 1
    std::string s1, s2; 1
    while (getline(std::cin, s1)) 1
    { 1
        std::cout << s1 << " 1\n"; 1
    } 1
         1
    while (getline(std::cin, s2)) 1
    { 1
        std::cout << s2 << "2\n"; 1
    } 1
} 1

有没有办法通过stdin 将两个单独的输入通过管道传输到程序?也就是说,如果我写类似cat main.cpp cat main.cpp | ./main 的东西,那么第一个输入将分配给s1,第二个输入分配给s2

【问题讨论】:

  • 不,这是不可能的。不是直接的任何方式。可以将输入以您想要的方式拼接到一个文件中,然后将该单个文件作为输入传递给程序。
  • 为什么不把这两个文件作为参数放到你的程序中呢?并从 2 个 ifstream 流而不是 cin 中读取? ./main main.cpp main.cpp

标签: c++ pipe user-input stdin


【解决方案1】:

AFAIK 这是不可能的,但您可以简单地使用两个包含您的输入的文件,将它们作为命令行参数传递并从中读取。

#include <iostream>
#include <fstream>

int main(int argc, char **argv)
{
    if (argc != 3) 
      return -1;

    std::ifstream ifs1(argv[1]);
    std::ifstream ifs2(argv[2]);

    if (!ifs1.is_open() || !ifs2.is_open())
      return -2;

    std::string s1, s2;
    while (getline(ifs1, s1))
    {
      std::cout << s1 << " 1\n";
    }

    while (getline(ifs2, s2))
    {
      std::cout << s2 << "2\n";
    }
    return 0;
}

然后这样称呼它:

./main main.cpp main.cpp

您甚至可以使其更加灵活,允许您读取任意数量的文件:

#include <iostream>
#include <fstream>

int main(int argc, char **argv)
{
    if (argc == 1) 
      return -1; // no input file given

    for (int i = 1; i < argc; ++i) { 
      std::ifstream ifs(argv[i]);

      if (!ifs.is_open()) {
        std::cout << argv[i] << ":file not found\n";
        continue;
      }

      std::string line;
      while (getline(ifs, line))
      {
        std::cout << line << " " << i << "\n";
      }
    }
}

【讨论】:

    【解决方案2】:

    cat 没有在文件之间放置任何类型的分隔符,因此管道另一侧的程序无法知道一个文件在哪里结束,下一个文件从哪里开始。你可以自己做,比如:

    { cat main.cpp; echo "**END**"; cat main.cpp; } | ./main
    

    并更改程序以查找 END 行:

    while (getline(std::cin, s1) && s1 != "**END**")
    {
        std::cout << s1 << " 1\n";
    }
    

    【讨论】:

    • 第二个cat main.cpp是这样分配给s2的吗?
    • 是的。第二个循环在读取**END** 后开始运行,因此它将获取第二个cat main.cpp 中的任何内容
    猜你喜欢
    • 1970-01-01
    • 2011-06-11
    • 2017-07-24
    • 2014-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-10
    • 2023-04-02
    相关资源
    最近更新 更多