freopen() equivalent for c++ streams

c++ c io
29,943

Solution 1

freopen also works with cin and cout. No need to search for something new.

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

Edit: From C++ standard 27.3.1:

The object cin controls input from a stream buffer associated with the object stdin, declared in <cstdio>.

So according to the standard, if we redirect stdin it will also redirect cin. Vice versa for cout.

Solution 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/

Solution 3

This newsgroup posting explores your options.

This is system dependent and the poster didn't indicate the system, but cin.clear() should work. I have tested the attached program on a UNIX system with AT&T version's of iostreams.

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

Yes, that works okay in cfront and TC++. In g++ where the problem first arose an additional action is required:

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

Though I note that this was in 1991, it should still work. Remember to use the now-standard iostream header, not iostream.h.

(BTW I found that post with the Google search terms "reopen cin c++", second result.)

Let us know how you get on. You could also just use freopen.

Share:
29,943
flight
Author by

flight

Updated on January 15, 2020

Comments

  • flight
    flight over 4 years

    When programming with c-style i/o I sometimes use freopen() to reopen stdin for testing purposes so that I don't have to retype the input over and over. I was wondering if there is an equivalent for c++ i/o streams. Also, I know that I can use pipes to redirect it on the command line/terminal/whateveritis but I was wondering if there was a way to do it inside my code (because as you can see, I'm not very knowledgeable about the cl/t/w).

  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE about 13 years
    No it does not. This program has undefined behavior.
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE about 13 years
    Mixing C stdio and C++ iostream usage like this is not valid and will result in implementation-defined or undefined behavior.
  • UmmaGumma
    UmmaGumma about 13 years
    @R.. I have use it lot of times on visual studio and g++ and I haven't any problems. Could you please explain what exactly is wrong with it?
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE about 13 years
    Just because something works on one implementation does not mean it's valid C++. Last I checked, it was at best implementation-defined whether changes to stdio were visible in the corresponding iostream or vice versa, and possibly worse.
  • UmmaGumma
    UmmaGumma about 13 years
    @R.. from cplusplus.com cin is an object of class istream that represents the standard input stream. It corresponds to the cstdio stream stdin. So cin is connected with stdin and if we are redirecting stdin we are also redirecting cin. Same thing with cout. cplusplus.com/reference/iostream/cin
  • flight
    flight about 13 years
    Sorry, I don't really get how this relates to my question. Could you explain more?
  • Lightness Races in Orbit
    Lightness Races in Orbit about 13 years
    @quasiverse: It's about re-opening STDIN through cin.
  • Lightness Races in Orbit
    Lightness Races in Orbit about 13 years
    @R: I worried so. Then there is no way to do what the OP asks without UB.
  • flight
    flight about 13 years
    Hmm, this seems to work but is there a way to do it with just c++ style input features?
  • UmmaGumma
    UmmaGumma about 13 years
    @quasiverse I don't think so. Even timus online judge is suggesting to use freopen for testing in C++. acm.timus.ru/help.aspx?topic=cpp
  • flight
    flight about 13 years
    @Ashot The cplusplus.com page was slightly ambiguous about it but timus seems pretty conclusive. Thanks.
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE about 13 years
    @Ashot: In that case, does this preclude a C++ implementation from performing its own buffering, etc. on top of stdio? It seems like it does...
  • yyny
    yyny almost 4 years
    @R..GitHubSTOPHELPINGICE You can disable this behavior with std::sync_with_stdio(false); so then C++ can do it's own buffering. See also this answer to a related question for how you can still redirect std::cout if you use std::sync_with_stdio(false).