163 votes

Comment rediriger cin et cout vers des fichiers ?

Comment puis-je rediriger cin a in.txt y cout a out.txt ?

8 votes

Rediriger cin vers une chaîne de caractères : stackoverflow.com/questions/4925150/redirect-cin-to-a-string - Rediriger cout vers une chaîne de caractères : stackoverflow.com/questions/1162068/

250voto

Nawaz Points 148870

Voici un exemple concret de ce que vous voulez faire. Lisez les commentaires pour savoir ce que fait chaque ligne du code. Je l'ai testé sur mon pc avec gcc 4.6.1 ; il fonctionne bien.

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

Vous pourriez sauver y rediriger en une seule ligne comme :

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

Aquí std::cin.rdbuf(in.rdbuf()) fixe std::cin's tampon pour in.rdbuf() et renvoie ensuite l'ancien tampon associé à std::cin . La même chose peut être faite avec std::cout - ou tout flux d'ailleurs.

J'espère que cela vous aidera.

4 votes

Dois-je fermer les fichiers avant de réinitialiser cin et cout en IO standard ?

3 votes

@updogliu : Non. Si vous voulez, vous pouvez utiliser in y out pour lire et écrire, in.txt y out.txt respectivement. En outre, les fichiers seront fermés automatiquement lorsque in y out sortir du champ d'application.

1 votes

Je préfère cette solution à celle de la freopen un parce que je ne peux plus obtenir mon stdout si j'utilise freopen . stackoverflow.com/questions/26699524/

96voto

Tsotne Tabidze Points 149

Il suffit d'écrire

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

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

19 votes

C'est rediriger stdout no cout .

5 votes

Cela redirigera aussi printf, ce qui dans certains cas peut être une bonne chose.

1 votes

@updogliu pour autant que je sache, stdout et cout sont toujours synchronisés.

29voto

Vadzim Points 4460

Voici un court extrait de code pour le shadowing cin/cout utile pour les concours de programmation :

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

Cela donne l'avantage supplémentaire que les fstreams simples sont plus rapides que les flux stdio synchronisés. Mais cela ne fonctionne que dans le cadre d'une seule fonction.

La redirection globale cin/cout peut s'écrire comme suit :

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

Notez que ios_base::sync_with_stdio réinitialise également std::cin.rdbuf . L'ordre est donc important.

Voir aussi Signification de ios_base::sync_with_stdio(false) ; cin.tie(NULL) ;

Les flux Std io peuvent également être facilement suivis pour la portée d'un seul fichier, ce qui est utile pour la programmation compétitive :

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

Mais dans ce cas, nous devons choisir std une par une et éviter using namespace std; car cela donnerait une erreur d'ambiguïté :

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
                   ^

Voir aussi Comment utiliser correctement les espaces de noms en C++ ? , Pourquoi "utiliser l'espace de noms std" est-il considéré comme une mauvaise pratique ? y Comment résoudre une collision de noms entre un espace de noms C++ et une fonction globale ?

14voto

user3260606 Points 16

En supposant que le nom de votre programme de compilation est x.exe et $ est l'interpréteur de commandes ou l'invite du système

$ x <infile >outfile 

prendra l'entrée de infile et sortira dans outfile .

2 votes

Cela n'est pas lié au C++ et échoue dans tout exemple non trivial, par exemple lorsque votre programme génère des processus enfants qui écrivent dans la console. Du moins, c'est le problème que j'ai rencontré lorsque j'ai essayé une telle redirection, d'où ma présence ici.

9voto

HaSeeB MiR Points 362

Essayez ceci pour rediriger cout à classer.

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

Lire l'article complet Utiliser std::rdbuf pour rediriger cin et cout

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X