How can I redirect cin
to in.txt
and cout
to out.txt
?
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.
in
and out
to read from and write to, in.txt
and out.txt
respectively. Also, the files will be closed automatically when in
and out
go out of scope. –
Tramway freopen
one because I can no longer get my stdout
back if I use freopen
. #26700024 –
Schneider delete
them? –
Margarine Just write
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
freopen("output.txt","w",stdout);
cout<<"write in file";
return 0;
}
std::sync_with_studio(false);
, although by default it is set to true
. –
Conjunction ofstream out("out.txt"); cout.rdbuf(out.rdbuf());
- only one extra line, and it's portable. Not soooo much simpler :) –
Forenamed 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 Significance of ios_base::sync_with_stdio(false); cin.tie(NULL);
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 How do you properly use namespaces in C++?, Why is "using namespace std" considered bad practice? and How to resolve a name collision between a C++ namespace and a global function?
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 .
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
cin
AND cout
. And sorry, most programmers will be able to strip that half of the accepted answer, that they don't need, if they redirect only cin
or only cout
. –
Margarine error: variable ‘std::ofstream out’ has initializer but incomplete type 53 | std::ofstream out("logs.txt");
and error: ‘cout’ in namespace ‘std’ does not name a type 55 | std::cout.rdbuf(out.rdbuf());
–
Cainozoic <fstream>
at the top of your code for std::ofstream
. This should i guess fix 1st error. And for std::cout
, well, that's with <iostream>
–
Understrapper 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
stdout
in that case? –
Terrain 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;
}
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
.
© 2022 - 2024 — McMap. All rights reserved.