Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to redirect printf output back into code?

i'm writing a little c++ app to wrap around the opencv haar training function (namely cvCreateTreeCascadeClassifier). The function throws a whole load of output to the console and I wish to parse this output so that I can populate various variables in my code.

The function I wish to use is not part of the actual openCV library; instead it has to be built with my code as part of the project. All of the output from the the function is via printf.

Question: Is it possible to intercept the printf statements before they end up on the console? I've managed to redirect them using freopen but this seems a little clumsy as I then need to parse the file and then delete it when the function call is finished. Also, the function is likely to be running for several hours (and possibly even weeks!) so the size of the file might be an issue if its constantly being appended too.

Requirements: I need this app to be c++ and to run on both windows and linux (but have no problem with conditional compile statements if need be). I would also like to be able to still see my cout and cerr messages on the console (just not the printf).

My googling has removed my will to live! Can anyone help with a solution via either code example or pointers to places I should be looking for an answer?

Thanks

like image 830
incubus Avatar asked May 06 '11 12:05

incubus


1 Answers

What you can do is:

  • create a pipe
  • make the writable end of the pipe the new stdout
  • read from the readable part of the pipe

Reading and writing should happen in different threads or you risk that your program starves on one end of the pipe.

Here's a sample how to do the redirection in 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;
}

This code should print

buf=>Hi there

(I'm using assert here, because I am too lazy to do real error checking for this example)

like image 79
Nordic Mainframe Avatar answered Oct 05 '22 08:10

Nordic Mainframe