21

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).

2
  • Can you read the same data twice when you have two file descriptors of the same stream? If not, you can always use multiple instances of std::cin in C++ Commented Mar 10, 2011 at 9:28
  • Possible duplicate of How to redirect cin and cout to files? Commented Jul 21, 2016 at 12:56

3 Answers 3

43

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.

Sign up to request clarification or add additional context in comments.

9 Comments

No it does not. This program has undefined behavior.
@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?
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.
@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
@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).
|
14
#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/

Comments

1

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.

4 Comments

Mixing C stdio and C++ iostream usage like this is not valid and will result in implementation-defined or undefined behavior.
Sorry, I don't really get how this relates to my question. Could you explain more?
@quasiverse: It's about re-opening STDIN through cin.
@R: I worried so. Then there is no way to do what the OP asks without UB.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.