freopen() equivalent for c++ streams
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
.
flight
Updated on January 15, 2020Comments
-
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 about 13 yearsNo it does not. This program has undefined behavior.
-
R.. GitHub STOP HELPING ICE about 13 yearsMixing C stdio and C++ iostream usage like this is not valid and will result in implementation-defined or undefined behavior.
-
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 about 13 yearsJust 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 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 redirectingstdin
we are also redirectingcin
. Same thing withcout
. cplusplus.com/reference/iostream/cin -
flight about 13 yearsSorry, I don't really get how this relates to my question. Could you explain more?
-
Lightness Races in Orbit about 13 years@quasiverse: It's about re-opening STDIN through
cin
. -
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 about 13 yearsHmm, this seems to work but is there a way to do it with just c++ style input features?
-
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 about 13 years@Ashot The cplusplus.com page was slightly ambiguous about it but timus seems pretty conclusive. Thanks.
-
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 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 redirectstd::cout
if you usestd::sync_with_stdio(false)
.