How to redirect cin and cout to files?
Here is an working example of what you want to do. Read the comments to know what each line in the code does. I've tested it on my pc with gcc 4.6.1; it works fine.
#include <iostream>
#include <fstream>
#include <string>
void f()
{
std::string line;
while(std::getline(std::cin, line)) //input from the file in.txt
{
std::cout << line << "\n"; //output to the file out.txt
}
}
int main()
{
std::ifstream in("in.txt");
std::streambuf *cinbuf = std::cin.rdbuf(); //save old buf
std::cin.rdbuf(in.rdbuf()); //redirect std::cin to in.txt!
std::ofstream out("out.txt");
std::streambuf *coutbuf = std::cout.rdbuf(); //save old buf
std::cout.rdbuf(out.rdbuf()); //redirect std::cout to out.txt!
std::string word;
std::cin >> word; //input from the file in.txt
std::cout << word << " "; //output to the file out.txt
f(); //call function
std::cin.rdbuf(cinbuf); //reset to standard input again
std::cout.rdbuf(coutbuf); //reset to standard output again
std::cin >> word; //input from the standard input
std::cout << word; //output to the standard input
}
You could save and redirect in just one line as:
auto cinbuf = std::cin.rdbuf(in.rdbuf()); //save and redirect
Here std::cin.rdbuf(in.rdbuf())
sets std::cin's
buffer to in.rdbuf()
and then returns the old buffer associated with std::cin
. The very same can be done with std::cout
— or any stream for that matter.
Hope that helps.
redirect cout to a file
Your program has undefined behavior.
coutbuf
is destructed when outstr
is destructed. Since you didn't reset the rdbuf
of cout
when the if
-block ended, cout
points to a dangling rdbuf
outside the if
-block.
Suggestion for cleanup. Always provide a return type for functions. Instead of
ucla();
use
void ucla();
Update, in response to OP's comment
To resolve the problem, it will be good to move all the "application code" to another function and call that function from main
. Leave the rdbuf
handling code in main
.
void ucla()
{
std::cout << "inside ucla" << std::endl;
}
void application_main()
{
std::cout << "here" << std::endl;
std::cout << "this file " << std::endl;
ucla();
}
int main()
{
const char* outName = argv[2];
std::string outFile(outName);
// Save the rdbuf of cout.
std::streambuf* coutbuf = std::cout.rdbuf();
termbuf = std::cout.rdbuf();
if (!outFile.empty())
{
std::ofstream outstr;
outstr.open(argv[2]);
std::cout.rdbuf(outstr.rdbuf());
// Needs to be here so that every use of cout will redirect the output
// to the file.
application_main();
}
else
{
// In this branch, use of cout will produce output in the console.
application_main();
}
// Restore the rdbuf of cout.
std::cout.rdbuf(coutbuf);
}
C++ function cout redirect to file
Assuming that print
is a void
function with its output hard-coded to cout
, there is nothing you can do: the output will be controlled by the execution environment's assignment of the output stream (console by default or a file redirect with >myoutput.txt
).
If you would like your program to control where the output goes, pass ostream&
to your print
function, and use it for the output:
void print(ostream& ostr) {
// use ostr instead of cout
ostr << "hello, world!" << endl;
}
If you want print
to output to console or the default output, call
print(cout);
If you want it to write to a file, make an ofstream
, and pass it to print
:
ofstream file("hello.txt");
print(file);
How to read a file using the redirected standard input, i.e. cin(Note:without using ifstream)
When file is redirected to stdin (standard input), you should read from std::cin
(instance of std::istream
) which is wrapper around stdin. std::basic_ifstream
is a subclass of std::basic_istream
, so most reading functions are available in both of them and you should familiar with them. Which means that you can use:
std::getline
to read file line by line:std::string s;
while(std::getline(std::cin, s)) {
std::cout << s << std::endl;
}operator >>
to read fields delimited by space character:while(std::cin) {
std::string s;
std::cin >> s;
std::cout << s << std::endl;
}
Check out full list of its operators and functions here: http://en.cppreference.com/w/cpp/io/basic_istream
How to redirect cout and cin?
The stream whose stream buffer you installed to std::cout
gets destructed right after installing the stream buffer:
std::ofstream out(argv[j]);
std::cout.rdbuf(out.rdbuf());
The first line needs to read
static std::ofstream out(argv[j]);
There may be other errors but this is the one I spotted.
How to redirect std::cout to file conditionally
Don't redirect std::cout
. Write your print in terms of a std::ostream &
parameter, and choose an appropriate std::ostream
to pass.
void MyClass::PPrintImpl(std::ostream & out)
{
out << "Will I be written to a file or to cout ?\n";
}
// a.k.a
std::ostream & operator <<(std::ostream & out, const MyClass &)
{
return out << "Will I be written to a file or to cout ?\n";
}
void MyClass::PPrint(bool ToFile) {
if (ToFile) {
std::ofstream fout("out.txt");
PPrintImpl(fout);
} else {
PPrintImpl(std::cout);
}
}
We pass std::ostream
s by reference because we the identity, not just the value of the stream object matters. We know this because they aren't copyable (the copy constructor is delete
d)
Redirect the copy of std::cout to the file
The simplest you can do is create an output stream class that does this:
#include <iostream>
#include <fstream>
class my_ostream
{
public:
my_ostream() : my_fstream("some_file.txt") {}; // check if opening file succeeded!!
// for regular output of variables and stuff
template<typename T> my_ostream& operator<<(const T& something)
{
std::cout << something;
my_fstream << something;
return *this;
}
// for manipulators like std::endl
typedef std::ostream& (*stream_function)(std::ostream&);
my_ostream& operator<<(stream_function func)
{
func(std::cout);
func(my_fstream);
return *this;
}
private:
std::ofstream my_fstream;
};
See this ideone link for this code in action: http://ideone.com/T5Cy1M
I can't currently check if the file output is done correctly though it shouldn't be a problem.
Copy std::cout inside a std::ofstream (c++)
You can't have a cake and eat it in the same time. Each stream object can only be tied to a single buffer, and std::cout
does not go backwards (you can write to it, but you can't read from it).
Because of that, while you can redirect cout
to go to any other stream, this will only be effective for output happened after redirection. There is absolutely no way for you to force the data which was printed to cout
before to appear in any other stream now, unless you have a way to recreate the data or extract it from some other storage (not cout).
Related Topics
Separating Class Code into a Header and Cpp File
How to Detect Whether There Is a Specific Member Variable in Class
Splitting Templated C++ Classes into .Hpp/.Cpp Files - Is It Possible
Is Uninitialized Local Variable the Fastest Random Number Generator
How Does the Import Library Work - Details
How to Remove from a Map While Iterating It
Differences Between Std::Make_Unique and Std::Unique_Ptr With New
Unmangling the Result of Std::Type_Info::Name
How to Track Down a "Double Free or Corruption" Error
What Happens If You Static_Cast Invalid Value to Enum Class
What Is a Converting Constructor in C++ ? What Is It For
Stringification - How Does It Work
Two Phase Lookup - Explanation Needed
Gcc Optimization Flag -O3 Makes Code Slower Than -O2
What Is the Lifetime of the Result of Std::String::C_Str()