How do I 'restore' my output (stdout) back to the terminal after redirecting it to a file. I want to be able to output to a file for a specific section of code, then close that file and put output back to the screen/terminal.

fprintf(stdout, "This will go to the terminal.\n");
stdout = fopen("/tmp/somefile.txt", "w");
fprintf(stdout, "This will go to the file /tmp/somefile.txt.\n");
...
fclose(stdout);
fprintf(stdout, "I WANT this to go to the terminal.\n");

Using this code, I get nothing after the close (obviously closing is wrong). How do I restore the output?

Dani AI

Generated

Two clean approaches, depending on whether you are using C or C++:

  • C++ iostreams: instead of touching the process-wide stdout, temporarily swap std::cout's stream buffer. This redirects only std::cout (not other FILE* streams), and is easier to scope and test.
#include <iostream>
#include <fstream>

int main() {
    std::cout << "This goes to the terminal\n";

    std::ofstream file("/tmp/somefile.txt");
    auto* saved = std::cout.rdbuf(file.rdbuf());  // redirect
    std::cout << "This goes to the file\n";
    std::cout.flush();                             // ensure it is written

    std::cout.rdbuf(saved);                        // restore
    std::cout << "Back to the terminal\n";
}

For multithreaded programs, this still affects all threads that write to std::cout. Guard with a mutex during the redirection window. Avoid mixing printf/fprintf with iostreams during redirection unless you understand the buffering interaction; flush both sides if you must mix. See cppreference: basic_ios::rdbuf.

  • POSIX C (Linux): the C standard library does not define a portable way to "undo" a redirection of stdout; the usual POSIX technique is to duplicate and later restore file descriptor 1. If you need a known terminal even when stdout was not originally a TTY, you can reattach to /dev/tty (if available) or to the original descriptor path such as /proc/self/fd/1 on Linux. Check all return values and fflush(stdout) before switching. See POSIX dup/dup2, freopen, and isatty.

Practical tip: for robustness in larger codebases, prefer passing an explicit FILE*/std::ostream& (or a logger interface) into functions instead of mutating global stdout. This avoids cross-thread surprises.

Recommended Answers

All 5 Replies

I should have specified that I am running in Linux and not windows.

So according to this page you gave, something like:

fprintf(stdout, "This will go to the terminal.\n");

FILE *myOutput;
myOutput = fopen("/tmp/somefile.txt", "w");
fprintf(myOutput, "This will go to the file /tmp/somefile.txt.\n");
...
fclose(myOutput);
fprintf(stdout, "I WANT this to go to the terminal.\n");

Yes, that should work as you expect it to.

This is easier if all your code is contained in one file, but what about multi-threaded programs - I will then have to pass this to every function, right?

According to the post, this is how its done (for anyone interested):

fprintf(stdout, "This will go to the terminal.\n");

//Save position of current standard output
fpos_t pos;
fgetpos(stdout, &pos);
int fd = dup(fileno(stdout));
freopen("/tmp/somefile.txt", "w", stdout);

fprintf(stdout, "This will go to the file /tmp/somefile.txt.\n");

//Flush stdout so any buffered messages are delivered
fflush(stdout);
//Close file and restore standard output to stdout - which should be the terminal
dup2(fd, fileno(stdout));
close(fd);
clearerr(stdout);
fsetpos(stdout, &pos);

fprintf(stdout, "This will go to the terminal.\n");
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.