Как перенаправить вывод 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 это кажется многообещающим, но я никогда не пробовал.
