freopen: возврат к исходному потоку

Мне нужно было перенаправить стандартный вывод в разные файлы, чтобы разделить некоторые произведенные отпечатки и вернуться к обычному стандартному выводу.

Я использовал freopen для переключения на файл следующим образом:

char name[80];
memset(name, 0, 80);
strcpy(name, "./scripts/asm/");
strcat(name, m_func->m_name->m_value);
strcat(name, ".shasm");
freopen(name, "w", stdout);

И это действительно работает, но в конце процесса (помните, что стандартный вывод перенаправляется много раз таким же образом) я не могу вернуть его к исходному стандартному выводу. Я пробовал следующее:

freopen("/dev/stdout", "w", stdout);

но, похоже, это не работает .. просто для информации, которую я разрабатываю на macosx.

Что я должен делать?

заранее спасибо


person Jack    schedule 04.11.2009    source источник
comment
Возможно, вы захотите добавить некоторые подробности, что происходит, когда вы выполняете финальную функцию freopen()? Возвращает NULL?   -  person unwind    schedule 04.11.2009


Ответы (2)


Этого можно добиться с помощью вызовов fileno, dup и dup2. Я пробовал это на Linux, не уверен, будет ли это работать на Mac, но я уверен, что вы получите некоторые эквивалентные функции для своей установки. Посмотрите, работает ли этот пример кода для вас. Извините за отсутствие обработки ошибок в коде. :)

    #include <stdio.h>

    main()
    {
        int    fd;
        fpos_t pos;

        printf("stdout, ");

        fflush(stdout);
        fgetpos(stdout, &pos);
        fd = dup(fileno(stdout));
        freopen("stdout.out", "w", stdout);

        f();

        fflush(stdout);
        dup2(fd, fileno(stdout));
        close(fd);
        clearerr(stdout);
        fsetpos(stdout, &pos);        /* for C9X */

        printf("stdout again\n");
    }

    f()
    {
    printf("stdout in f()");
    }
person Vinit Dhatrak    schedule 04.11.2009
comment
Изменение этого параметра на #include ‹errno.h›, а затем проверка возвращаемых значений вызовов fgetpos/fsetpos показывает проблемы в Linux: if (fgetpos(stdout, &pos)) perror(fgetpos); - person Rhys Ulerich; 20.12.2010

Это похоже на обходной путь решения вашей проблемы. Почему бы просто не открыть каждый файл с помощью fopen(), а затем записать в его FILE * с помощью fputs, fprintf, fwrite и т. д.? Нет необходимости перенаправлять стандартный вывод.

person Nick Meyer    schedule 04.11.2009
comment
Вероятно, потому что (много) кода пишется без указания выходного потока, например. используя простые вызовы printf(). Перенаправление stdout — это способ обернуть этот код и заставить его писать в нужное место, не изменяя его. Только предположить, конечно. - person unwind; 04.11.2009
comment
@unwind ваше предположение верно, это наиболее вероятный вариант использования freopen. - person Vinit Dhatrak; 04.11.2009
comment
Я действительно могу подтвердить, что это причина. Это компилятор, и я всегда использовал printf для печати ассемблерного кода (например, MOV $1, 4.5f) при его создании, и теперь я не хочу тратить время на замену вещей. - person Jack; 04.11.2009
comment
Простой sed или perl скрипт для выполнения всех замен и исправления сломанного кода был бы намного лучше, чем эти уродливые хаки. - person R.. GitHub STOP HELPING ICE; 10.03.2011