【问题标题】:C++ : Read(Write) from(to) a file if provided otherwise fall back to std::cin (std::cout)C ++:如果提供,则从(到)文件读取(写入)文件,否则回退到 std::cin (std::cout)
【发布时间】:2021-09-08 15:41:13
【问题描述】:

我有这个需求。如果提供,则从文件读取或写入文件,否则回退给好朋友std::cin / std::cout,如:

// pseudo code for problem statement.

int main(int argc, char* argv[]) 
{
  istream reader;
  ostrea writer;
  if (argc > 1) 
  {
    // we have path to our file in argv[] 
    reader = ifstream(infile);
    writer = ofstream(outfile);
  }
  else
  {
    reader = cin;
    writer = cout;
  }
 // rest of code
}

本质上,即使我的想法很复杂,有没有办法实现类似的目标。 谢谢!

使用的环境:C++ 11、14、17。

编辑#1: 详细说明if条件,如果程序被调用为

$: driver "input_file.txt" "output_file.txt"

它应该从这些文件中做IO,相反,如果这样调用,

$: driver < "input_file.txt" > "output_file.txt" 

它应该使用std::cinstd::cout

// 编辑结束#1

我正在阅读参考资料here,我在想这是否有帮助?

【问题讨论】:

  • 创建一个函数read(),像这样重载它:read(ifstream&amp;, ofstream&amp;); read(istream&amp;, ostream&amp;); 详细说明您已经提出的if 条件。

标签: c++ file-io


【解决方案1】:

您可以看看以下方法:

void read_write(ifstream&, ofstream&);  // Overloaded reader-writer
void read_write(istream&, ostream&);

int main(int argc, char* argv[]) {
    if (argc > 1) {
        auto infile = argv[1];
        auto outfile = argv[2]
        read_write(infile, outfile);
    } else read_write(cin, cout);
    // rest of code
}

【讨论】:

  • +1 这比我的版本更优雅,更可测试,但如果您仍然需要访问这些读者或作者,您也可以考虑使用指针
  • @ben10 这里只是一个大纲,其余的将取决于其他因素。如果我需要进一步访问读取器/写入器,我会将它们作为类的实例来介绍。
  • 您对rdbuf() 的看法?此外,如果我有很多变量要设置,我必须将它们传递给函数或使它们成为 globla (ew)。可以通过任何方式缓解这种情况吗?
  • @RaviTiwari 不确定我是否完全理解,但如果我理解了,您可以使用指向 std::ostreamstd::istream(作者和读者)的指针,正如我所提到的,然后传递它们。或者正如@rawrex 所说,将它们添加到某个类中
  • @RaviTiwari 抽象的术语太多,无法确定要走的路。一般来说,如果您有一些数据要管理,表明其元素之间的语义一致性,将其打包到数据结构中(例如struct)是明智的。另外,考虑在内部引入对象来管理所有细微差别,但提供简洁明了的界面以供main使用。
【解决方案2】:

您可以使用指向std::ostreamstd::istream 的基类的指针:

#include <iostream>

int main(int argc, char* argv[]) 
{
  std::istream* reader;
  std::ostream* writer;
  bool deleteNeeded;
  if (argc > 1) 
  {
    // mark them for deletion, using a bool, for example
    deleteNeeded = true;
    // we have path to our file in argv[] 
    reader = new ifstream(infile);
    writer = new ofstream(outfile);
  }
  else
  {
    // mark for no deletion, setting the same bool
    deleteNeeded = false;

    reader = &std::cin;
    writer = &std::cout;
  }
  // rest of code
  if(deleteNeeded) 
  {
    delete reader; delete writer;
  }
}

或者使用可以重新分配的引用之类的东西。

【讨论】:

  • 如果你打算这样做,至少使用智能指针
  • 你需要一个自定义的 std::cin 删除器
  • “类似于可以重新分配的参考”?那不是指针吗?
  • 它是,或者一些花哨的引用包装器,它也是一个指针,但具有更友好的 (?) 语法
【解决方案3】:

我涉足了它发布建议并感谢大家,这就是我想出的。

#include <iostream>
#include <fstream>

void solve(std::istream& in, std::ostream& out) {
  int n;
  in >> n;
  out
    << n << " squared is " 
    << static_cast<uint64_t>(n)*n << " !" 
    << std::endl;
}

int main(int argc, char* argv[]) {
  if (argc > 1) {
    std::ifstream in(argv[1]);
    std::ofstream out(argv[2]);
    solve(in, out);
  } else {
    solve(std::cin, std::cout);
  } 
}

// call : ./driver in.txt out.txt

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多