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).
- 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++Jonas Bötel– Jonas Bötel2011-03-10 09:28:05 +00:00Commented Mar 10, 2011 at 9:28
- Possible duplicate of How to redirect cin and cout to files?Vadzim– Vadzim2016-07-21 12:56:45 +00:00Commented Jul 21, 2016 at 12:56
3 Answers
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.
9 Comments
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/cinstd::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).#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"; } Comments
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
cin.