-1

I want to switch between writing to the file and to the stdout I can't use fprintf, but only printf and freopen something like this:

for(size_t i;i<100;++i)
{
     if(i%2)
     {
        freopen("tmp","w",stdout);
        printf("%d\n",i);
     }
     else
     {
        //return to write to stdout?
        printf("%d\n",i);
     }
}

How can I return to writing to the stdout?

Update

I write cross-platform application and dup can't be used.

YAKOVM
  • 9,805
  • 31
  • 116
  • 217

2 Answers2

2

Never use freopen. It cannot achieve what you want, and it's a very dangerous function. If it fails, the only safe thing you can do is immediately terminate the program or ensure that stdout is never accessed again.

There is a way to do what you want on POSIX systems with dup and dup2. It looks something like this:

fflush(stdout);
int old_stdout = dup(1);
int new_stdout = open("whatever", O_WRDONLY|O_CREAT, 0666);
dup2(new_stdout, 1);
close(new_stdout);
/* use new stdout here */
fflush(stdout);
dup2(old_stdout, 1);
close(old_stdout);
R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • I'm really not sure what you're basing your dire warnings against `freopen` on. got any references? also, http://pubs.opengroup.org/onlinepubs/009695399/functions/freopen.html says `freopen` is commonly used to reattach `stdin`, `stdout` and `stderr` to other files. – Hasturkun Aug 29 '11 at 14:11
  • See this text in the link you provided: "The original stream shall be closed regardless of whether the subsequent open succeeds." Thus, `stdout` is closed if opening the new file fails, and since it's been closed, any function that uses `stdout` (e.g. `printf`) now uses an invalid `FILE *` and thus invokes undefined behavior. – R.. GitHub STOP HELPING ICE Aug 29 '11 at 14:23
  • I don't think there's anything stopping you from reassigning these, so you can still handle this gracefully. – Hasturkun Aug 29 '11 at 14:29
  • Assigning to `stdout` is not allowed. In fact glibc is just about the **only** system that allows it, and while they allow it explicitly in the documentation, assignments to `stdout` are not actually honored by all internal functions (some of them fail to see it due to symbol visibility or copy relocation related bugs...). Per the standards, `stdin`, `stdout`, and `stderr` are macros that expand to expressions of type `FILE *`. There is no reason to expect they should even be lvalues, much less modifiable. – R.. GitHub STOP HELPING ICE Aug 29 '11 at 14:35
  • Right. I'd temper the warning slightly though, since it should be safe to use `freopen` at program initialization time, where closing one of the standard handles could be handled. – Hasturkun Aug 29 '11 at 14:43
0

You need to dup the file descriptors, and reopen to the open descriptor. Why can't you use fprintf? (Is this homework?)

tripleee
  • 175,061
  • 34
  • 275
  • 318