Как работает перенаправление stdout? - PullRequest
5 голосов
/ 07 августа 2011

Код ниже перенаправляет стандартный вывод в файл fname, а затем перенаправляет обратно в исходный стандартный вывод. Он отлично работает для меня. Но я не могу понять, как это на самом деле работает. Если кто-нибудь может помочь мне понять, я оценю это.

    printf("\n This is console");
    fflush(stdout);
    fgetpos(stdout, &pos);
    fd = dup(fileno(stdout));
    freopen(fname, "a+", stdout);   

    printf("inside file op");  

    fflush(stdout);
    dup2(fd,fileno(stdout));
    close(fd);
    clearerr(stdout);
    fsetpos(stdout, &pos);
    printf("\nBack to Console");

1 Ответ

14 голосов
/ 07 августа 2011

Давайте пройдемся по этой строке построчно.Первая строка печатает что-то в stdout:

printf("\n This is console");

Затем она сбрасывает stdout, поэтому все оставшиеся в буфере данные отправляются в stdout и не смешиваются с данными файла:

fflush(stdout);

Теперь мы сохраняем нашу текущую позицию в stdout, потому что в противном случае, если stdout уже был направлен в файл, мы могли бы (?) Перезаписать его более ранние части.

fgetpos(stdout, &pos);

Теперь мы клонируем файловый дескриптор того, что в данный момент stdout.Так как мы собираемся изменить то, куда указывает stdout, нам нужно сохранить копию оригинала:

fd = dup(fileno(stdout));

Теперь, когда у нас все сохранено, мы можем снова открыть stdout как файл:

freopen(fname, "a+", stdout);

На данный момент, stdout был перенаправлен в файл.Теперь мы можем напечатать на нем:

printf("inside file op");  

Теперь мы закончили печать в файл.Нам нужно очистить stdout (теперь файл), чтобы он не смешивался с обычными stdout данными:

fflush(stdout);

После этого мы клонируем оригинальный дескриптор файла stdout поверхтекущий дескриптор stdout.

dup2(fd,fileno(stdout));

Клонированный теперь можно закрыть:

close(fd);

Я не совсем уверен, почему это здесь, но это устраняет все ошибки, которые произошлизапись в файл:

clearerr(stdout);

Теперь мы восстановим нашу позицию в stdout.Опять же, насколько я знаю, это полезно только в том случае, если изначально он был перенаправлен в файл:

fsetpos(stdout, &pos);

Теперь мы вернулись к исходному stdout, поэтому мы можем снова напечатать:

printf("\nBack to Console");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...