How to redirect cin and cout to files?

C++

C++ Problem Overview


How can I redirect cin to in.txt and cout to out.txt?

C++ Solutions


Solution 1 - C++

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.

Solution 2 - C++

Just write

#include <cstdio>
#include <iostream>
using namespace std;

int main()
{
    freopen("output.txt","w",stdout);
    cout<<"write in file";
    return 0;
}

Solution 3 - C++

Here is a short code snippet for shadowing cin/cout useful for programming contests:

#include <bits/stdc++.h>

using namespace std;

int main() {
    ifstream cin("input.txt");
    ofstream cout("output.txt");
     
    int a, b;   
    cin >> a >> b;
    cout << a + b << endl;
}

This gives additional benefit that plain fstreams are faster than synced stdio streams. But this works only for the scope of single function.

Global cin/cout redirect can be written as:

#include <bits/stdc++.h>

using namespace std;

void func() {
    int a, b;
    std::cin >> a >> b;
    std::cout << a + b << endl;
}

int main() {
    ifstream cin("input.txt");
    ofstream cout("output.txt");
     
    // optional performance optimizations    
    ios_base::sync_with_stdio(false);
    std::cin.tie(0);

    std::cin.rdbuf(cin.rdbuf());
    std::cout.rdbuf(cout.rdbuf());

    func();
}

Note that ios_base::sync_with_stdio also resets std::cin.rdbuf. So the order matters.

See also https://stackoverflow.com/questions/31162367/significance-of-ios-basesync-with-stdiofalse-cin-tienull

Std io streams can also be easily shadowed for the scope of single file, which is useful for competitive programming:

#include <bits/stdc++.h>

using std::endl;

std::ifstream cin("input.txt");
std::ofstream cout("output.txt");

int a, b;

void read() {
    cin >> a >> b;
}

void write() {
    cout << a + b << endl;
}

int main() {
    read();
    write();
}

But in this case we have to pick std declarations one by one and avoid using namespace std; as it would give ambiguity error:

error: reference to 'cin' is ambiguous
     cin >> a >> b;
     ^
note: candidates are: 
std::ifstream cin
    ifstream cin("input.txt");
             ^
    In file test.cpp
std::istream std::cin
    extern istream cin;  /// Linked to standard input
                   ^

See also https://stackoverflow.com/questions/41590/how-do-you-properly-use-namespaces-in-c, https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice and https://stackoverflow.com/questions/3871474/how-to-resolve-a-name-collision-between-a-c-namespace-and-a-global-function

Solution 4 - C++

assuming your compiles prog name is x.exe and $ is the system shell or prompt

$ x <infile >outfile 

will take input from infile and will output to outfile .

Solution 5 - C++

Try this to redirect cout to file.

#include <iostream>
#include <fstream>

int main()
{
    /** backup cout buffer and redirect to out.txt **/
    std::ofstream out("out.txt");

    auto *coutbuf = std::cout.rdbuf();
    std::cout.rdbuf(out.rdbuf());

    std::cout << "This will be redirected to file out.txt" << std::endl;

    /** reset cout buffer **/
    std::cout.rdbuf(coutbuf);

    std::cout << "This will be printed on console" << std::endl;

    return 0;
}

Read full article Use std::rdbuf to Redirect cin and cout

Solution 6 - C++

If your input file is in.txt, you can use freopen to set stdin file as in.txt

freopen("in.txt","r",stdin);

if you want to do the same with your output:

freopen("out.txt","w",stdout);

this will work for std::cin (if using c++), printf, etc...

This will also help you in debugging your code in clion, vscode

Edit
If you want to reset stdin

fclose(stdin);
stdin = fdopen(0, "r"); //reopen: 0 is file descriptor of std input

and to reset stdout

fclose(stdout);
stdout = fdopen(1, "w"); //reopen: 1 is file descriptor of std output

Solution 7 - C++

The accepted answer shows the right way to redirect cin and cout. You need to construct another stream object whose life time exceeds that of cin or cout. If you want to write a function works like freopen, you can alloc an array for each stream to be redirected, to save the allocated stream objects.

#include <iostream>
#include <string>
#include <fstream>
#include <vector>

using namespace std;

template<typename>
    struct fstream_traits { };
template<typename CharT, typename Traits>
    struct fstream_traits<basic_istream<CharT, Traits>> { using type = basic_ifstream<CharT, Traits>; };
template<typename CharT, typename Traits>
    struct fstream_traits<basic_ostream<CharT, Traits>> { using type = basic_ofstream<CharT, Traits>; };

template <typename Stream>
void redirect(Stream& str, string filename)
{
    using fstream_type = typename fstream_traits<Stream>::type;
    static int index = std::ios_base::xalloc();
    if (str.pword(index) == nullptr)
    {
        str.pword(index)= new vector<ios_base*>{};
        str.register_callback([](ios_base::event event, std::ios_base& stream, int index) {
            if (event == ios_base::erase_event)
            {
                for (auto fs : *(vector<ios_base*>*)stream.pword(index))
                    delete fs;
                delete (vector<ios_base*>*)stream.pword(index);
            }
        }, index);
    }
    vector<ios_base*>* list = (vector<ios_base*>*)str.pword(index);
    list->push_back(new fstream_type{filename});
    str.rdbuf(dynamic_cast<fstream_type*>(list->back())->rdbuf())->~basic_streambuf();
}

int main()
{
    redirect(cout, "out.txt");
    cout << "Redirected text!";
    return 0;
}

The template and alias are not required if you explicitly use istream/ostream instead of Stream.

Solution 8 - C++

I/O Redirection in C++

https://www.geeksforgeeks.org/io-redirection-c/

// Cpp program to redirect cout to a file
#include <fstream>
#include <iostream>
#include <string>
 
using namespace std;
 
int main()
{
    fstream file;
    file.open("cout.txt", ios::out);
    string line;
 
    // Backup streambuffers of  cout
    streambuf* stream_buffer_cout = cout.rdbuf();
    streambuf* stream_buffer_cin = cin.rdbuf();
 
    // Get the streambuffer of the file
    streambuf* stream_buffer_file = file.rdbuf();
 
    // Redirect cout to file
    cout.rdbuf(stream_buffer_file);
 
    cout << "This line written to file" << endl;
 
    // Redirect cout back to screen
    cout.rdbuf(stream_buffer_cout);
    cout << "This line is written to screen" << endl;
 
    file.close();
    return 0;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionupdogliuView Question on Stackoverflow
Solution 1 - C++NawazView Answer on Stackoverflow
Solution 2 - C++Tsotne TabidzeView Answer on Stackoverflow
Solution 3 - C++VadzimView Answer on Stackoverflow
Solution 4 - C++Ahmed EidView Answer on Stackoverflow
Solution 5 - C++HaseeB MirView Answer on Stackoverflow
Solution 6 - C++Vishal SinghView Answer on Stackoverflow
Solution 7 - C++Tuff ContenderView Answer on Stackoverflow
Solution 8 - C++Mihir PatelView Answer on Stackoverflow