How to Redirect Cin and Cout to Files

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::ostreams 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 deleted)

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



Leave a reply



Submit