Как перенаправить вывод printf обратно в код? - PullRequest
9 голосов
/ 06 мая 2011

Я пишу небольшое приложение на c ++, чтобы обернуть вокруг обучающую функцию opencv haar (а именно cvCreateTreeCascadeClassifier).Функция генерирует всю нагрузку вывода на консоль, и я хочу проанализировать этот вывод, чтобы я мог заполнить различные переменные в моем коде.

Функция, которую я хочу использовать, не является частью реальной библиотеки openCV;вместо этого он должен быть построен с моим кодом как часть проекта.Все выходные данные функции выполняются через printf.

Вопрос. Можно ли перехватить операторы printf до того, как они попадут на консоль?Мне удалось перенаправить их с помощью freopen, но это кажется немного неуклюжим, поскольку мне нужно проанализировать файл и затем удалить его, когда вызов функции завершен.Кроме того, функция, вероятно, будет работать в течение нескольких часов (и, возможно, даже недель!), Поэтому размер файла может быть проблемой, если он постоянно добавляется.

Требования: мне нужно, чтобы это приложение былоc ++ и для запуска как в Windows, так и в Linux (но не возникает проблем с условными инструкциями компиляции, если это необходимо).Я также хотел бы иметь возможность видеть мои сообщения cout и cerr на консоли (только не printf).

Мой поиск в Google снял мое желание жить!Может ли кто-нибудь помочь с решением с помощью примера кода или указателей на места, где я должен искать ответ?

Спасибо

Ответы [ 3 ]

7 голосов
/ 06 мая 2011

Что вы можете сделать, это:

  • создать трубу
  • делает доступным для записи конец канала новым stdout
  • чтение из читаемой части трубы

Чтение и запись должны происходить в разных потоках, иначе вы рискуете, что ваша программа голодает на одном конце канала.

Вот пример того, как сделать перенаправление в Unix и Windows:


#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
/* gcc defined unix */
#ifdef unix
#include <unistd.h>
#endif
#ifdef WIN32
#include <io.h>
#define pipe(X) _pipe(X,4096,O_BINARY)     
#define fileno _fileno
#define dup2 _dup2
#define read _read

#endif
#include <assert.h>

int main()
{
    int fds[2]; 
    int res; 
    char buf[256];
    int so; 

    res=pipe(fds);
    assert(res==0); 

    so=fileno(stdout);
    // close stdout handle and make the writable part of fds the new stdout.
    res=dup2(fds[1],so);
    assert(res!=-1); 

    printf("Hi there\n");
    fflush(stdout);
    // reading should happen in a different thread

    res=read(fds[0],buf,sizeof(buf)-1);
    assert(res>=0 && res<sizeof(buf));
    buf[res]=0;
    fprintf(stderr,"buf=>%s\n",buf);
    return 0;
}

Этот код должен печатать

buf=>Hi there

(здесь я использую assert, потому что мне лень проверять ошибки в этом примере)

0 голосов
/ 06 мая 2011

Взгляните на: http://www.unix.com/programming/136225-reading-stdout-pipe.html это кажется многообещающим, но я никогда не пробовал.

0 голосов
/ 06 мая 2011

Инкапсулируйте lib в приложение и передайте вывод приложения в ваше приложение. Теперь напишите сценарий, чтобы вам не приходилось каждый раз запускать приложения вместе с конвейером.

...