Cin ve cout dosyalara nasıl yönlendirilir?


Yanıtlar:


219

İşte yapmak istediğiniz şeyin çalışan bir örneği. Koddaki her satırın ne işe yaradığını öğrenmek için yorumları okuyun. Bilgisayarımda gcc 4.6.1 ile test ettim; iyi çalışıyor.

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

Şu şekilde kaydedebilir ve tek bir satırda yeniden yönlendirebilirsiniz :

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

Burada tamponu olarak std::cin.rdbuf(in.rdbuf())ayarlar ve ardından ilişkili eski tamponu döndürür . Aynı şey, bu konudaki herhangi bir akışla da yapılabilir .std::cin'sin.rdbuf()std::cinstd::cout

Umarım yardımcı olur.


4
Cin ve cout'u standart IO'ya sıfırlamadan önce dosyaları kapatmam gerekir mi?
updogliu

3
@updogliu: Hayır İsterseniz, kullanabilirsiniz inve outgelen ve yazma okumak için, in.txtve out.txtsırasıyla. Ayrıca, dosyalar otomatik olarak kapanacak inve outkapsam dışına çıkar.
Nawaz

Bu çözümü daha çok seviyorum freopençünkü kullanırsam artık stdoutgeri dönemem freopen. stackoverflow.com/questions/26699524/…
xxks-kkk

88

Sadece yaz

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

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

14
Bu yönlendirmedir stdout, değil cout.
updogliu

5
Bu, printf'i de yönlendirecektir, bu bazı durumlarda iyi bir şey olabilir.
JDiMatteo

5
@AkshayLAradhya Ayarladığınızda değil std::sync_with_studio(false);, varsayılan olarak ayarlı olmasına rağmen true.
vsoftco

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

4
Cevaplar işlevsellik açısından eşit olsaydı, bunun C ++ eşdeğeri ofstream out("out.txt"); cout.rdbuf(out.rdbuf());- yalnızca bir ekstra satır ve taşınabilirdir. Değil soooo çok daha basit :)
nevelis

19

İşte cin / cout gölgeleme için yarışmaları programlamak için yararlı olan kısa bir kod parçası:

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

Bu, düz f akışlarının senkronize edilmiş standart akışlardan daha hızlı olması ek fayda sağlar. Ancak bu yalnızca tek işlevin kapsamı için çalışır.

Global cin / cout yönlendirmesi şu şekilde yazılabilir:

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

Bunun ios_base::sync_with_stdioda sıfırlandığını unutmayın std::cin.rdbuf. Yani sıra önemlidir.

Ayrıca bkz . İos_base :: sync_with_stdio (false); cin.tie (NULL);

Std io akışları, rekabetçi programlama için yararlı olan tek dosyanın kapsamı için kolayca gölgelenebilir:

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

Ancak bu durumda, stdbeyanları tek tek using namespace std;seçmeli ve belirsizlik hatası vereceğinden kaçınmalıyız :

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
                   ^

Ayrıca bkz . C ++ 'da ad alanlarını nasıl düzgün kullanıyorsunuz? , "Std ad alanını kullanmak" neden kötü bir uygulama olarak kabul edilir? ve C ++ ad alanı ile genel işlev arasındaki ad çakışması nasıl çözülür?


15

Derlemelerinizin program adının x.exe ve $ sistem kabuğu veya komut istemi olduğunu varsayarsak

$ x <infile >outfile 

dosyadan girdi alacak ve çıktı dosyaya gönderilecektir.


Bu, C ++ ile ilgili değildir ve önemsiz olmayan herhangi bir örnekte başarısız olur, örneğin, programınız konsola yazan çocuk süreçleri ortaya çıkardığında. En azından böyle bir yönlendirmeyi denediğimde karşılaştığım sorun bu, bu yüzden buradayım.
ashrasmun

5

Cout'u dosyaya yeniden yönlendirmek için bunu deneyin .

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

Yazının tamamını okuyun cin ve cout'u yeniden yönlendirmek için std :: rdbuf kullanın


1
Soru yaklaşık 6 yıl önce (2012'de) yanıtlanmıştı, ancak şimdi 2018'de bir yanıt eklediniz. Cevabınız kabul edilen yanıtla aynı. Öyleyse , ekleyecek yeni bir şeyiniz olmadığı halde bunu neden gönderdiğini merak ediyorum ?
Nawaz

Cevabım sadece cout versiyonunu özel olarak vurgular ve detaylı cevap aşağıdaki bağlantıda verilmiştir.
HaseeB Mir

Cevabınızda kabul edilen cevapta bulunmayan yenilikler nelerdir ?
Nawaz

2
Cevabım hem cout hem de cin için yönlendirmeyi karıştırmıyor,
sürümüm
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.