如何将 cin 和 cout 重定向到文件?

如何将 cin重定向到 in.txt,将 cout重定向到 out.txt

235423 次浏览

这里有一个你想要做的工作示例。阅读注释以了解代码中的每一行是做什么的。我已经用 gcc4.6.1在我的电脑上测试过,它工作得很好。

#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
}

你可以把 拯救再次询问写成:

auto cinbuf = std::cin.rdbuf(in.rdbuf()); //save and redirect

这里,std::cin.rdbuf(in.rdbuf())std::cin's缓冲区设置为 in.rdbuf(),然后返回与 std::cin关联的旧缓冲区。对于 std::cout和任何 溪流都可以做同样的事情。

希望能帮上忙。

写吧

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


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

假设您的编译程序名称为 x.exe $是系统 shell 或提示符

$ x <infile >outfile

将从文件中获取输入,并将输出到文件外。

下面是一个用于跟踪 cin/cout 的简短代码片段,对于编程竞赛非常有用:

#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;
}

这样做的另一个好处是,普通流比同步的 stdio 流更快。 但这只适用于单个函数的范围。

全局 cin/cout 重定向可以写为:

#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();
}

注意,ios_base::sync_with_stdio也会重置 std::cin.rdbuf,所以顺序很重要。

参见 对 ios _ base 的重要性: sync _ with _ stdio (false) ; cin.tie (NULL) ;

标准音频流也可以很容易地隐藏在单个文件的范围内,这对于竞争性编程很有用:

#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();
}

但在这种情况下,我们必须一个一个地选择 std声明,并避免 using namespace std;,因为它会产生歧义性错误:

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
^

参见 如何在 C + + 中正确使用名称空间?为什么“使用名称空间 std”被认为是不好的做法?如何解决 C + + 名称空间和全局函数之间的名称冲突?

尝试将 Cout重定向到文件。

#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;
}

阅读全文 使用 std: : rdbuf 重定向细胞因子和细胞因子

如果输入文件是 in.txt,则可以使用 freopen 将 stdin 文件设置为 in.txt

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

如果希望对输出执行相同的操作:

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

这将适用于 std: : cin (如果使用 c + +)、 printf 等。

这也将帮助您在 clion vscode 中调试代码

剪辑
如果您想重置标准输入

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

重置标准输出

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

C + + 中的 I/O 重定向

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;
}

接受的答案显示了重定向 cincout的正确方法。您需要构造另一个流对象,其生存期超过 cincout的生存期。如果希望编写一个类似于 freopen的函数,可以为每个要重定向的流分配一个数组,以保存分配的流对象。

#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;
}

如果显式使用 istream/ostream而不是 Stream,则不需要模板和别名。