Próbowałem bada różnicę pomiędzy cout
, cerr
oraz clog
w Internecie, ale nie mógł znaleźć idealne odpowiedź. Nadal nie wiem, kiedy którego użyć. Czy ktoś może mi wyjaśnić za pomocą prostych programów i zilustrować idealną sytuację, kiedy należy użyć którego?
Odwiedziłem tę stronę, która pokazuje mały program na cerr
i clog
, ale dane wyjściowe tam uzyskane można również uzyskać za pomocą cout
. Więc jestem zdezorientowany co do dokładnego zastosowania każdego z nich.
stdout
,stdin
(dlacin
) istderr
używa go domyślnie. Uważam, żeclog
jest to tylkocerr
zmiana buforująca.Odpowiedzi:
stdout
istderr
są różnymi strumieniami, mimo że oba odnoszą się domyślnie do wyjścia konsoli. Przekierowanie (potokowanie) jednego z nich (np.program.exe >out.txt
) Nie wpłynie na inne.Generalnie,
stdout
powinno być używane do rzeczywistego wyjścia programu, podczas gdy wszystkie informacje i komunikaty o błędach powinny być drukowanestderr
, tak aby jeśli użytkownik przekierował wyjście do pliku, komunikaty informacyjne nadal były drukowane na ekranie, a nie do pliku wyjściowego.źródło
Zwykle używasz
std::cout
do normalnego wyjścia,std::cerr
do błędów istd::clog
do "rejestrowania" (co może oznaczać cokolwiek chcesz, żeby oznaczało).Główną różnicą jest to, że
std::cerr
nie jest buforowany tak jak dwa pozostałe.W odniesieniu do starego C
stdout
istderr
,std::cout
odpowiada nastdout
, podczasstd::cerr
istd::clog
obu odpowiada nastderr
(oprócz tego, żestd::clog
jest buforowany).źródło
clog
również wysyła docerr
. Na tej podstawie, którą z nich wybierzesz? Jeśliclog
jest to normalne dla „rejestrowania”, dlaczego miałbym chcieć, aby to przechodziło do strumienia błędów? Dzienniki bardziej przypominają „normalne dzienniki” (inaczejcout
) niż błędy.cerr
iclog
używają standardowego wyjścia "błędu", aleclog
są buforowane, co może być przyczyną bardziej podobnego działaniacout
. Który wybrać do wyświetlania błędów? To zależy, jak sądzę, z większej liczby powodów, niż potrafię wymienić, i trzeba to rozstrzygać w zależności od przypadku.Standardowy strumień wyjściowy (cout):
cout
jest instancjąostream
klasy.cout
służy do generowania danych wyjściowych na standardowym urządzeniu wyjściowym, którym jest zwykle ekran wyświetlacza. Dane potrzebne do wyświetlenia na ekranie są wstawiane do standardowego strumienia wyjściowego (cout
) za pomocą operatora wstawiania (<<
).Niesbuforowany standardowy strumień błędów (cerr):
cerr
jest to standardowy strumień błędów używany do wyświetlania błędów. Jest to również instancjaostream
klasy. Ponieważcerr
jest niebuforowany , jest używany, gdy musimy natychmiast wyświetlić komunikat o błędzie. Nie ma żadnego bufora do przechowywania komunikatu o błędzie i wyświetlania go później.Buforowany standardowy strumień błędów (zatkanie): jest to również wystąpienie
ostream
klasy i służy do wyświetlania błędów, ale w przeciwieństwiecerr
do błędu jest najpierw wstawiany do buforu i przechowywany w buforze, dopóki nie zostanie całkowicie wypełniony.Dalsza lektura: podstawowe-wejście-wyjście-c
źródło
until it is not fully filled.
- czy to nie powinno mówićuntil it IS fully filled
?Różnica między tymi 3 strumieniami polega na buforowaniu.
Sprawdź poniższy kod i uruchom DEBUG w 3 liniach: f (std :: clog), f (std :: cerr), f (std :: out), a następnie otwórz 3 pliki wyjściowe, aby zobaczyć, co się stało. Możesz zamienić te 3 linie, aby zobaczyć, co się stanie.
#include <iostream> #include <fstream> #include <string> void f(std::ostream &os) { std::cin.clear(); // clear EOF flags std::cin.seekg(0, std::cin.beg); // seek to begin std::string line; while(std::getline(std::cin, line)) //input from the file in.txt os << line << "\n"; //output to the file out.txt } void test() { std::ifstream in("in.txt"); std::ofstream out("out.txt"), err("err.txt"), log("log.txt"); std::streambuf *cinbuf = std::cin.rdbuf(), *coutbuf = std::cout.rdbuf(), *cerrbuf = std::cerr.rdbuf(), *clogbuf = std::clog.rdbuf(); std::cin.rdbuf(in.rdbuf()); //redirect std::cin to in.txt! std::cout.rdbuf(out.rdbuf()); //redirect std::cout to out.txt! std::cerr.rdbuf(err.rdbuf()); std::clog.rdbuf(log.rdbuf()); f(std::clog); f(std::cerr); f(std::cout); std::cin.rdbuf(cinbuf); std::cout.rdbuf(coutbuf); std::cerr.rdbuf(cerrbuf); std::clog.rdbuf(clogbuf); } int main() { test(); std::cout << "123"; }
źródło
źródło
Z wersji roboczej standardowego dokumentu C ++ 17:
Dyskusja...
cout
pisze dostdout
;cerr
iclog
dostderr
Standardowe wyjście (
stdout
) ma na celu odbieranie z programu bezbłędnych, niediagnostycznych danych wyjściowych, takich jak dane wyjściowe z pomyślnego przetwarzania, które mogą być wyświetlane użytkownikowi końcowemu lub przesyłane strumieniowo do dalszego etapu przetwarzania.Standard Error (
stderr
) jest przeznaczony do diagnostyki danych wyjściowych, takich jak ostrzeżenia i komunikaty o błędach, które wskazują, że program nie wygenerował lub mógł nie wygenerować danych wyjściowych, których użytkownik mógłby się spodziewać. Te dane wejściowe mogą być wyświetlane użytkownikowi końcowemu, nawet jeśli dane wyjściowe są przesyłane potokiem do dalszego etapu przetwarzania.cin
icerr
są przywiązanicout
Obaj opróżniają się
cout
przed samodzielną obsługą operacji we / wy. Zapewnia to, że podpowiedzi wysyłane docout
są widoczne przed blokami programu, z których mają odczytać dane wejściowecin
, oraz że wcześniejsze wyjście docout
jest opróżniane przed zapisaniem błęducerr
, co utrzymuje komunikaty w chronologicznej kolejności ich generowania, gdy oba są kierowane do tego samego terminala / pliku / itp..Kontrastuje to z
clog
- jeśli tam napiszesz, nie będzie buforowany i nie będzie z niczym powiązany, więc przed opróżnieniem będzie buforował przyzwoite ilości logowania. Zapewnia to największą przepustowość komunikatów, ale oznacza, że komunikaty mogą nie być szybko widoczne dla potencjalnego konsumenta czytającego terminal lub śledzącego dziennik.źródło
Zarówno cout, jak i clog są buforowane, ale cerr nie jest buforowany, a wszystkie z nich są predefiniowanymi obiektami, które są instancjami klasy ostream. Podstawowym zastosowaniem tych trzech jest cout jest używane do standardowego wejścia, podczas gdy clog i cerr jest używane do wyświetlania błędów. Głównym powodem, dla którego cerr nie jest buforowany, może być to, że przypuśćmy, że masz kilka wyjść w buforze i w kodzie jest wymieniony wyjątek błędu, a następnie musisz natychmiast wyświetlić ten błąd, co może być skutecznie wykonane przez cerr .
Proszę, popraw mnie jeśli się mylę.
źródło