Как перенаправить вывод printf обратно в код?

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

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

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

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

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

спасибо

3 ответов


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

  • создать канал
  • сделайте записываемый конец трубы новым 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 здесь, потому что я слишком ленив, чтобы сделать реальную проверку ошибок для этого примера)


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


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