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