簡體   English   中英

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

[英]How to redirect cin and cout to files?

如何將cin重定向到in.txt並將cout重定向到out.txt

這是您想要做什么的工作示例。 閱讀注釋以了解代碼中每一行的作用。 我已經在我的電腦上用 gcc 4.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;
}

下面是一段用於屏蔽 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;
}

這提供了額外的好處,即普通 fstreams 比同步 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);

Std io 流也可以很容易地在單個文件的范圍內隱藏,這對於競爭性編程很有用:

#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++ 中正確使用命名空間? 為什么“使用命名空間標准”被認為是不好的做法? 以及如何解決 C++ 命名空間和全局函數之間的名稱沖突?

假設您的編譯程序名稱是 x.exe 並且 $ 是系統外殼或提示

$ x <infile >outfile 

將從 infile 獲取輸入並將輸出到 outfile 。

試試這個將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 重定向 cin 和 cout

接受的答案顯示了重定向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 ,則不需要模板和別名。

如果你的輸入文件是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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM