2010-03-08 1 views
10

Czy ktoś może wyjaśnić różnicę między cerr cout a clog i dlaczego proponowane są różne obiekty?Pytanie dotyczące cerr cout and clog

wiem, że różnice są następujące:

1) Cout może przekierowany ale cerr nie może

2) zatyka można użyć bufor.

Jestem zdezorientowany co do punktu 2, jestem wdzięczny, jeśli ktoś może go bardziej rozwinąć.

+17

Kto powiedział, że cerr nie może zostać przekierowany? Ciągle to robię! –

Odpowiedz

3

Wyjście buforowe jest zwykle znacznie szybsze niż niebuforowane. Więc jeśli chcesz szybko zapisać ogromną ilość danych w dzienniku (ale nie obchodziło cię to, czy faktycznie tam się skończyło), używałbyś raczej zatkania niż cerr.

Wszystkie strumienie można normalnie przekierować, przy założeniu, że mają mało kompetentny system operacyjny, ale jest to poza standardem C++, który nie ma pojęcia "przekierowanie".

+3

Być może zechcesz opracować nieco z pozytywnej strony pozytywu cerr/non-buffered-io - tzn. Strumień jest zapisywany, nawet jeśli coś złego dzieje się zaraz po operacji zapisu. –

+0

@RaphaelSP To właśnie miałem na myśli przez "(ale nie przejmowałem się, czy to rzeczywiście tam się skończyło)" –

+1

@Neil: OP jest pozornie zdezorientowany co do tego, co to jest buforowanie, myślę, że sformułowanie może być wyraźniejsze :) –

2

Oba można przekierować.
W większości implementacji cerr nie będzie buforowany, nie jestem pewien, czy jest to oficjalny wymóg POSIX, ale to szalone, że mamy buforowany strumień błędów.

Powód oddzielnych strumieni wynika z filozofii unix, że wyjście jednego programu jest wejściem do następnego. Jeśli "ls" idzie prosto do "sortowania", łatwiej jest wyświetlać błędy na konsoli, niż pisać sortowanie, aby zrozumieć, czy dane wejściowe są komunikatem o błędzie lub częścią tekstu, który chcesz posortować.

16

Wyjście może być zbuforowane lub niebuforowane. W przypadku buforowanego wyjścia implementacja zapisuje wszystkie dane wyjściowe, dopóki nie będzie wygodne zapisanie ich na dysku (lub gdziekolwiek). To jest dobre i wydajne, ale jeśli program się zawiesza, prawdopodobnie pewne dane zostaną utracone. Implementacja musi zapisywać niebuforowane dane wyjściowe na dysku, tak jak się pojawia, co może spowolnić proces z dużą ilością zapisów na dysku, ale jeśli nie wystąpi awaria programu podczas zapisywania, zostanie ona zapisana na dysku.

Nie ma rzeczywistej funkcjonalnej różnicy między standardowym wyjściem a standardowym błędem; to tylko dwa różne strumienie wyjściowe, które można przekierować osobno. Filozofia Unix łączenia narzędzi w łańcuchy polega na tym, że standardowe wyjście będzie miało odpowiednie wyjście, aby przejść do wejścia następnego narzędzia, a to prawie wymaga oddzielnego strumienia dla komunikatów o błędach.

Tak więc, cout zapisuje na standardowe wyjście i jest buforowany. Użyj tego dla normalnego wyjścia. cerr zapisuje do standardowego strumienia błędów i jest niebuforowany. Użyj tego w przypadku komunikatów o błędach. clog zapisuje do standardowego strumienia błędów, ale jest buforowany. Jest to przydatne do rejestrowania wykonania, ponieważ nie koliduje ze standardowym wyjściem, ale jest wydajne (kosztem, że koniec dziennika może zostać utracony, jeśli program ulegnie awarii).

1
cout-Screen output(stdout) 
clog-Buffered output of standard error(stderr) 
cerr-Standard error device output (stderr) 
0

Jednym z głównych powodów korzystania buforowane i niebuforowane wyjście można zaobserwować biorąc awarię programu jako przykład.

Należy rozważyć program, który wyprowadza coś do pliku dziennika. I nagle program się rozbił. Być może zainteresowałeś się tym, w jaki sposób błąd spowodował awarię, ale jeśli użyłeś metody clog (buforowanej) dla wszystkich dzienników i błędów, możesz nie zobaczyć wszystkich tych informacji, ponieważ mogą one nadal znajdować się w buforze, gdy program się zawiesi, dlatego informacje w bufor jest również tracony.

Tak więc w przypadku błędów, najczęściej używane jest cerr, ponieważ jest niebuforowane i nie może być żadnej sytuacji teraz, gdy poważny błąd został utracony podczas awarii programu tylko dlatego, że był w buforze.