【问题标题】:freopen() equivalent for c++ streamsfreopen() 等效于 c++ 流
【发布时间】:2011-07-12 13:35:04
【问题描述】:

当使用 c 风格的 i/o 进行编程时,我有时会使用 freopen() 来重新打开标准输入以进行测试,这样我就不必一遍又一遍地重新输入输入。我想知道是否有 c++ i/o 流的等价物。另外,我知道我可以使用管道在命令行/终端/whateveritis 上重定向它,但我想知道是否有办法在我的代码中执行此操作(因为如您所见,我对cl/t/w)。

【问题讨论】:

  • 当你有同一个流的两个文件描述符时,你能两次读取相同的数据吗?如果没有,您总是可以在 C++ 中使用 std::cin 的多个实例

标签: c++ c io


【解决方案1】:

freopen 也适用于cincout。无需寻找新的东西。

freopen("input.txt", "r", stdin); // redirects standard input
freopen("output.txt", "w", stdout); // redirects standard output

int x;
cin >> x; // reads from input.txt
cout << x << endl; // writes to output.txt

编辑:来自 C++ 标准 27.3.1:

对象 cin 控制来自与对象 stdin 关联的流缓冲区的输入,在 @​​987654327@ 中声明。

所以按照标准,如果我们重定向stdin,它也会重定向cincout 反之亦然。

【讨论】:

  • 不,它没有。该程序具有未定义的行为。
  • @R.. 我在 Visual Studio 和 g++ 上使用过很多次,我没有任何问题。你能解释一下它到底有什么问题吗?
  • 仅仅因为某些实现在一个实现上有效并不意味着它是有效的 C++。最后我检查了一下,充其量实现定义了对 stdio 的更改是否在相应的 iostream 中可见,反之亦然,甚至可能更糟。
  • @R.. from cplusplus.com cin is an object of class istream that represents the standard input stream. It corresponds to the cstdio stream stdin. 所以 cin 与标准输入相连,如果我们重定向 stdin,我们也重定向 cin。与cout 相同。 cplusplus.com/reference/iostream/cin
  • @R..GitHubSTOPHELPINGICE 您可以使用 std::sync_with_stdio(false); 禁用此行为,这样 C++ 就可以进行自己的缓冲。另请参阅this answer to a related question,了解如何在使用std::sync_with_stdio(false) 时重定向std::cout
【解决方案2】:
#include <iostream>
#include <fstream>

int main() {

  // Read one line from stdin
  std::string line;
  std::getline(std::cin, line);
  std::cout << line << "\n";

  // Read a line from /etc/issue
  std::ifstream issue("/etc/issue");
  std::streambuf* issue_buf = issue.rdbuf();
  std::streambuf* cin_buf = std::cin.rdbuf(issue_buf);
  std::getline(std::cin, line);
  std::cout << line << "\n";

  // Restore sanity and read a line from stdin
  std::cin.rdbuf(cin_buf);
  std::getline(std::cin, line);
  std::cout << line << "\n";
}

http://www.cplusplus.com/reference/iostream/ios/rdbuf/

【讨论】:

    【解决方案3】:

    This 新闻组发帖探索您的选择。

    这是系统相关的,海报没有说明 系统,但 cin.clear() 应该可以工作。我已经测试了附件 在 UNIX 系统上使用 AT&T 版本的 iostreams 程序。

    #include <iostream.h>
    int main()
    {
        for(;;) {
            if ( cin.eof() ) {
                cout << "EOF" << endl;
                cin.clear();
            }
            char c ;
            if ( cin.get(c) ) cout.put(c) ;
        }
    } 
    

    是的,这在 cfront 和 TC++ 中运行良好。 在首先出现问题的 g++ 中,需要执行额外的操作:

      cin.clear();
      rewind ( _iob ); // Seems quite out of place, doesn't it?
                       // cfront also accepts but doesn't
                       // require this rewind. 
    

    虽然我注意到这是在 1991 年,但它应该仍然有效。请记住使用现在标准的 iostream 标头,而不是 iostream.h

    (顺便说一句,我发现那个帖子带有 Google 搜索词“reopen cin c++”,第二个结果。)

    让我们知道您的进展情况。你也可以只使用freopen

    【讨论】:

    • 像这样混合使用 C stdio 和 C++ iostream 是无效的,会导致实现定义或未定义的行为。
    • 对不起,我真的不明白这与我的问题有什么关系。你能解释更多吗?
    • @quasiverse:这是关于通过cin重新打开STDIN。
    • @R:我很担心。那么没有UB就没有办法做OP要求的事情。
    猜你喜欢
    • 2015-07-03
    • 2017-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多