Bagaimana cara mengarahkan cin dan cout ke file?


Jawaban:


219

Ini adalah contoh kerja dari apa yang ingin Anda lakukan. Baca komentar untuk mengetahui apa yang dilakukan setiap baris dalam kode. Saya sudah mengujinya di pc saya dengan gcc 4.6.1; ini bekerja dengan baik.

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

Anda dapat menyimpan dan mengarahkan ulang hanya dalam satu baris sebagai:

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

Di sini std::cin.rdbuf(in.rdbuf())set std::cin'sbuffer ke in.rdbuf()dan kemudian mengembalikan buffer lama yang terkait dengannya std::cin. Hal yang sama dapat dilakukan dengan std::cout- atau aliran apa pun dalam hal ini.

Semoga itu bisa membantu.


4
Apakah saya perlu menutup file sebelum saya mengatur ulang cin dan cout ke IO standar?
updogliu

3
@ updogliu: Tidak. Jika Anda mau, Anda dapat menggunakan indan outmembaca dan menulis, in.txtdan out.txtmasing - masing. Juga, file akan ditutup secara otomatis kapan indan outkeluar dari ruang lingkup.
Nawaz

Saya suka solusi ini freopenkarena saya tidak bisa mendapatkan stdoutkembali jika saya gunakan freopen. stackoverflow.com/questions/26699524/…
xxks-kkk

88

Cukup tulis

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

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

14
Itu mengarahkan stdout, bukan cout.
updogliu

5
Ini akan mengarahkan printf juga, yang dalam beberapa kasus mungkin merupakan hal yang baik.
JDiMatteo

5
@AkshayLAradhya Tidak ketika Anda mengatur std::sync_with_studio(false);, meskipun secara default diatur ke true.
vsoftco

2
@ PřemyslŠťastný mengapa?
reggaeguitar

4
Jika jawabannya sama dalam fungsionalitas, setara C ++ dari ini adalah ofstream out("out.txt"); cout.rdbuf(out.rdbuf());- hanya satu baris tambahan, dan ini portabel. Tidak terlalu sederhana :)
nevelis

19

Berikut ini adalah cuplikan kode pendek untuk membayangi cin / cout yang berguna untuk kontes pemrograman:

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

Ini memberikan manfaat tambahan bahwa stream biasa lebih cepat daripada stream stdio yang disinkronkan. Tetapi ini hanya berfungsi untuk ruang lingkup fungsi tunggal.

Redirect cin / cout global dapat ditulis sebagai:

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

Perhatikan bahwa ios_base::sync_with_stdiojuga mengatur ulang std::cin.rdbuf. Jadi pesanan itu penting.

Lihat juga Signifikansi ios_base :: sync_with_stdio (false); cin.tie (NULL);

Std io stream juga dapat dengan mudah dibayangi untuk cakupan file tunggal, yang berguna untuk pemrograman kompetitif:

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

Tetapi dalam kasus ini kita harus memilih stddeklarasi satu per satu dan menghindari using namespace std;karena akan memberikan kesalahan ambiguitas:

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
                   ^

Lihat juga Bagaimana Anda menggunakan ruang nama dengan benar di C ++? , Mengapa "menggunakan namespace std" dianggap praktik buruk? dan Bagaimana cara menyelesaikan tabrakan nama antara namespace C ++ dan fungsi global?


15

anggap kompilasi nama prog Anda adalah x.exe dan $ adalah shell sistem atau prompt

$ x <infile >outfile 

akan mengambil input dari infile dan akan menampilkan ke outfile.


Itu tidak terkait C ++ dan gagal dalam contoh non-sepele, misalnya ketika program Anda memunculkan proses anak yang menulis ke konsol. Setidaknya itulah masalah yang saya temui ketika saya mencoba pengalihan seperti itu, maka mengapa saya di sini.
ashrasmun

5

Coba ini untuk mengarahkan cout ke 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;
}

Baca artikel lengkap Gunakan std :: rdbuf untuk Redirect cin and cout


1
Pertanyaannya telah dijawab hampir 6 tahun yang lalu (tahun 2012), namun Anda telah menambahkan jawaban sekarang di tahun 2018. Jawaban Anda sama dengan jawaban yang diterima. Jadi saya bertanya-tanya mengapa Anda memposting ini ketika Anda tidak memiliki sesuatu yang baru untuk ditambahkan?
Nawaz

Jawaban saya hanya menyoroti versi cout khusus dan jawaban terinci disediakan di tautan di bawah ini.
HaseeB Mir

Apa yang baru dalam jawaban Anda yang tidak ada dalam jawaban yang diterima ?
Nawaz

2
Jawaban saya tidak mencampur pengalihan cout dan cin, versi saya terpisah agar lebih mudah dibaca
HaseeB Mir
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.