Oto działający przykład tego, co chcesz zrobić. Przeczytaj komentarze, aby dowiedzieć się, co robi każdy wiersz w kodzie. Przetestowałem to na moim komputerze z gcc 4.6.1; to działa dobrze.
#include<iostream>#include<fstream>#include<string>voidf(){
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
}
}
intmain(){
std::ifstream in("in.txt");
std::streambuf *cinbuf = std::cin.rdbuf(); //save old bufstd::cin.rdbuf(in.rdbuf()); //redirect std::cin to in.txt!std::ofstream out("out.txt");
std::streambuf *coutbuf = std::cout.rdbuf(); //save old bufstd::cout.rdbuf(out.rdbuf()); //redirect std::cout to out.txt!std::string word;
std::cin >> word; //input from the file in.txtstd::cout << word << " "; //output to the file out.txt
f(); //call functionstd::cin.rdbuf(cinbuf); //reset to standard input againstd::cout.rdbuf(coutbuf); //reset to standard output againstd::cin >> word; //input from the standard inputstd::cout << word; //output to the standard input
}
Możesz zapisać i przekierować w jednej linii jako:
auto cinbuf = std::cin.rdbuf(in.rdbuf()); //save and redirect
Tutaj std::cin.rdbuf(in.rdbuf())ustawia std::cin'sbufor na, in.rdbuf()a następnie zwraca stary bufor skojarzony z std::cin. To samo można zrobić z std::cout- lub dowolnym strumieniem, jeśli o to chodzi.
Czy muszę zamknąć pliki, zanim zresetuję cin i cout do standardowego IO?
updogliu
3
@updogliu: Nie. Jeśli chcesz, możesz używać ini, odpowiednio, outdo odczytu i zapisu in.txtoraz out.txt. Ponadto pliki zostaną automatycznie zamknięte ini outwyjdą poza zakres.
Nawaz
1
To rozwiązanie podoba mi się bardziej niż to, freopenponieważ nie mogę już odzyskać swoich stdoutpleców, jeśli używam freopen. stackoverflow.com/questions/26699524/ ...
xxks-kkk
92
Tylko napisz
#include<cstdio>#include<iostream>usingnamespacestd;
intmain(){
freopen("output.txt","w",stdout);
cout<<"write in file";
return0;
}
Gdyby odpowiedzi były równe pod względem funkcjonalności, odpowiednikiem tego w C ++ byłoby ofstream out("out.txt"); cout.rdbuf(out.rdbuf());- tylko jedna dodatkowa linia i jest przenośna. Nie tak dużo prostsze :)
nevelis
22
Oto krótki fragment kodu do shadowingu cin / cout przydatnego w konkursach programistycznych:
#include<bits/stdc++.h>usingnamespacestd;
intmain(){
ifstream cin("input.txt");
ofstream cout("output.txt");
int a, b;
cin >> a >> b;
cout << a + b << endl;
}
Daje to dodatkową korzyść, że zwykłe strumienie fstreams są szybsze niż synchronizowane strumienie stdio. Ale to działa tylko w zakresie pojedynczej funkcji.
Globalne przekierowanie cin / cout można zapisać jako:
#include<bits/stdc++.h>usingnamespacestd;
voidfunc(){
int a, b;
std::cin >> a >> b;
std::cout << a + b << endl;
}
intmain(){
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();
}
Zauważ, że ios_base::sync_with_stdiorównież resetuje sięstd::cin.rdbuf . Więc kolejność ma znaczenie.
Strumienie standardowe io można również łatwo tworzyć cienie w zakresie pojedynczego pliku, co jest przydatne w przypadku programowania konkurencyjnego:
#include<bits/stdc++.h>usingstd::endl;
std::ifstream cin("input.txt");
std::ofstream cout("output.txt");
int a, b;
voidread(){
cin >> a >> b;
}
voidwrite(){
cout << a + b << endl;
}
intmain(){
read();
write();
}
Ale w tym przypadku musimy wybierać stddeklaracje pojedynczo i unikać, using namespace std;ponieważ dałoby to błąd niejednoznaczności:
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::cinextern istream cin; /// Linked to standard input
^
Nie jest to związane z C ++ i kończy się niepowodzeniem w żadnym nietrywialnym przykładzie, na przykład gdy program odradza procesy potomne, które zapisują na konsoli. Przynajmniej taki problem napotkałem próbując takiego przekierowania, stąd dlaczego tu jestem.
ashrasmun
8
Spróbuj tego, aby przekierować cout do pliku.
#include<iostream>#include<fstream>intmain(){
/** 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;
return0;
}
Odpowiedź na to pytanie została udzielona prawie 6 lat temu (w 2012 r.), Ale dodałeś odpowiedź teraz w 2018 r. Twoja odpowiedź jest taka sama, jak zaakceptowana odpowiedź. Zastanawiam się więc, dlaczego opublikowałeś to, skoro nie masz nic nowego do dodania?
Nawaz
Moja odpowiedź podkreśla tylko wersję cout, a szczegółowa odpowiedź znajduje się w linku poniżej.
HaseeB Mir
1
Co nowego w Twojej odpowiedzi, czego nie ma w zaakceptowanej odpowiedzi?
Nawaz
2
Moja odpowiedź nie łączy przekierowań zarówno cout, jak i cin, moja wersja oddziela się, aby była bardziej czytelna
Odpowiedzi:
Oto działający przykład tego, co chcesz zrobić. Przeczytaj komentarze, aby dowiedzieć się, co robi każdy wiersz w kodzie. Przetestowałem to na moim komputerze z gcc 4.6.1; to działa dobrze.
#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 }
Możesz zapisać i przekierować w jednej linii jako:
auto cinbuf = std::cin.rdbuf(in.rdbuf()); //save and redirect
Tutaj
std::cin.rdbuf(in.rdbuf())
ustawiastd::cin's
bufor na,in.rdbuf()
a następnie zwraca stary bufor skojarzony zstd::cin
. To samo można zrobić zstd::cout
- lub dowolnym strumieniem, jeśli o to chodzi.Mam nadzieję, że to pomoże.
źródło
in
i, odpowiednio,out
do odczytu i zapisuin.txt
orazout.txt
. Ponadto pliki zostaną automatycznie zamkniętein
iout
wyjdą poza zakres.freopen
ponieważ nie mogę już odzyskać swoichstdout
pleców, jeśli używamfreopen
. stackoverflow.com/questions/26699524/ ...Tylko napisz
#include <cstdio> #include <iostream> using namespace std; int main() { freopen("output.txt","w",stdout); cout<<"write in file"; return 0; }
źródło
stdout
, a niecout
.std::sync_with_studio(false);
, chociaż domyślnie jest ustawione natrue
.ofstream out("out.txt"); cout.rdbuf(out.rdbuf());
- tylko jedna dodatkowa linia i jest przenośna. Nie tak dużo prostsze :)Oto krótki fragment kodu do shadowingu cin / cout przydatnego w konkursach programistycznych:
#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; }
Daje to dodatkową korzyść, że zwykłe strumienie fstreams są szybsze niż synchronizowane strumienie stdio. Ale to działa tylko w zakresie pojedynczej funkcji.
Globalne przekierowanie cin / cout można zapisać jako:
#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(); }
Zauważ, że
ios_base::sync_with_stdio
również resetuje sięstd::cin.rdbuf
. Więc kolejność ma znaczenie.Zobacz też Znaczenie ios_base :: sync_with_stdio (false); cin.tie (NULL);
Strumienie standardowe io można również łatwo tworzyć cienie w zakresie pojedynczego pliku, co jest przydatne w przypadku programowania konkurencyjnego:
#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(); }
Ale w tym przypadku musimy wybierać
std
deklaracje pojedynczo i unikać,using namespace std;
ponieważ dałoby to błąd niejednoznaczności: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 ^
Zobacz także Jak prawidłowo używać przestrzeni nazw w C ++? , Dlaczego „używanie standardowej przestrzeni nazw” jest uważane za złą praktykę? i Jak rozwiązać konflikt nazw między przestrzenią nazw C ++ a funkcją globalną?
źródło
zakładając, że nazwa programu kompilacji to x.exe, a $ to powłoka systemu lub znak zachęty
weźmie dane wejściowe z infile i wyprowadzi do pliku wyjściowego.
źródło
Spróbuj tego, aby przekierować cout do pliku.
#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; }
Przeczytaj cały artykuł Użyj std :: rdbuf do przekierowania cin i cout
źródło