4

There is plenty of documentation about redirecting stdout and stderr to a file instead of the console. How do you redirect it back again? The code below shows my intention, but outputs "stdout is printed to console" only once.

I'm guessing I need to grab the console output buffer, store it somewhere, redirect stdout to file, then restore the console buffer?

#pragma warning(disable:4996)

#include <cstdio>

int main()
{
    std::printf("stdout is printed to console\n");

    if (std::freopen("redir.txt", "w", stdout)) {
        std::printf("stdout is redirected to a file\n"); // this is written to redir.txt
        std::fclose(stdout);

        std::printf("stdout is printed to console\n");
    }

    getchar();
    return 0;
}
Ben
  • 427
  • 5
  • 17
  • Duplicate of https://stackoverflow.com/questions/15155314/redirect-stdout-and-stderr-to-the-same-file-and-restore-it?rq=1 – Rene Oct 10 '18 at 10:15
  • Possible duplicate of [Redirect stdout and stderr to the same file and restore it](https://stackoverflow.com/questions/15155314/redirect-stdout-and-stderr-to-the-same-file-and-restore-it) – Peter VARGA Oct 10 '18 at 10:33
  • The link above indirectly answered my question, but I have not marked this as duplicate because my answer below: 1) is the direct answer, 2) Contains pertinent information about deprecation that I can't add to the articles above because of insufficient reputation or because it doesn't answer that persons actual question. – Ben Oct 10 '18 at 13:32

1 Answers1

1

With thanks to the articles in the comments above I found the information I needed. The dup and dup2 functions were what I needed. Note that based on info here dup and dup2 are deprecated in favour or _dup and _dup2. A working example can be found on MSDN here, but is duplicated below in case the link breaks in the future.

// crt_dup.c
// This program uses the variable old to save
// the original stdout. It then opens a new file named
// DataFile and forces stdout to refer to it. Finally, it
// restores stdout to its original state.

#include <io.h>
#include <stdlib.h>
#include <stdio.h>

int main( void )
{
   int old;
   FILE *DataFile;

   old = _dup( 1 );   // "old" now refers to "stdout"
                      // Note:  file descriptor 1 == "stdout"
   if( old == -1 )
   {
      perror( "_dup( 1 ) failure" );
      exit( 1 );
   }
   _write( old, "This goes to stdout first\n", 26 );
   if( fopen_s( &DataFile, "data", "w" ) != 0 )
   {
      puts( "Can't open file 'data'\n" );
      exit( 1 );
   }

   // stdout now refers to file "data"
   if( -1 == _dup2( _fileno( DataFile ), 1 ) )
   {
      perror( "Can't _dup2 stdout" );
      exit( 1 );
   }
   puts( "This goes to file 'data'\n" );

   // Flush stdout stream buffer so it goes to correct file
   fflush( stdout );
   fclose( DataFile );

   // Restore original stdout
   _dup2( old, 1 );
   puts( "This goes to stdout\n" );
   puts( "The file 'data' contains:" );
   _flushall();
   system( "type data" );
}
Ben
  • 427
  • 5
  • 17