How to Redirect Cout to Console in Linux

How to redirect cout to console in linux?

You need to define what you mean by the 'console' and what you mean by 'redirect'. If you're running a program in some context where its output has been redirected somewhere else, and you want to re-redirect it to the controlling terminal (what many people mean when they say 'console'), you can redirect to /dev/tty, eg:

program >/dev/tty

when you run the program. The above might be a line in a shell script, or be a string that is passed as an argument to system(3) -- it depends on how you're starting the program.

If you want to change where the output is going within the program, you can open up a new streambuf referring to what you want, and use ios::rdbuf to redirect to it:

filebuf *console = new filebuf();
console->open("/dev/tty");
if (!console->is_open()) {
cerr << "Can't open console" << endl;
} else {
cout.ios::rdbuf(console);
}

How to redirect output to a file and stdout

The command you want is named tee:

foo | tee output.file

For example, if you only care about stdout:

ls -a | tee output.file

If you want to include stderr, do:

program [arguments...] 2>&1 | tee outfile

2>&1 redirects channel 2 (stderr/standard error) into channel 1 (stdout/standard output), such that both is written as stdout. It is also directed to the given output file as of the tee command.

Furthermore, if you want to append to the log file, use tee -a as:

program [arguments...] 2>&1 | tee -a outfile

Redirecting output to file then back to console in C++

Probably what you are looking for is rdbuf() as mentioned by doomista in the comments.

Here is a way to redirect Output.

#include <iostream>
#include <fstream>

int main()
{
/** backup cout buffer and redirect to out.txt **/
std::ofstream out("out.txt");

auto *coutbuf = std::cout.rdbuf();
std::cout.rdbuf(out.rdbuf());

std::cout << "This will be redirected to file out.txt" << std::endl;

/** reset cout buffer **/
std::cout.rdbuf(coutbuf);

std::cout << "This will be printed on console" << std::endl;

return 0;
}

How to redirect cin and cout to files?

Here is an working example of what you want to do. Read the comments to know what each line in the code does. I've tested it on my pc with gcc 4.6.1; it works fine.

#include <iostream>
#include <fstream>
#include <string>

void f()
{
std::string line;
while(std::getline(std::cin, line)) //input from the file in.txt
{
std::cout << line << "\n"; //output to the file out.txt
}
}
int main()
{
std::ifstream in("in.txt");
std::streambuf *cinbuf = std::cin.rdbuf(); //save old buf
std::cin.rdbuf(in.rdbuf()); //redirect std::cin to in.txt!

std::ofstream out("out.txt");
std::streambuf *coutbuf = std::cout.rdbuf(); //save old buf
std::cout.rdbuf(out.rdbuf()); //redirect std::cout to out.txt!

std::string word;
std::cin >> word; //input from the file in.txt
std::cout << word << " "; //output to the file out.txt

f(); //call function

std::cin.rdbuf(cinbuf); //reset to standard input again
std::cout.rdbuf(coutbuf); //reset to standard output again

std::cin >> word; //input from the standard input
std::cout << word; //output to the standard input
}

You could save and redirect in just one line as:

auto cinbuf = std::cin.rdbuf(in.rdbuf()); //save and redirect

Here std::cin.rdbuf(in.rdbuf()) sets std::cin's buffer to in.rdbuf() and then returns the old buffer associated with std::cin. The very same can be done with std::cout — or any stream for that matter.

Hope that helps.

How to redirect printf output back into code?

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)

How to redirect the output back to the screen after freopen(out.txt, a, stdout)

I can't think of a way to do this in a cross-platform manner, but on GNU/Linux systems (and maybe other POSIX-compliant ones, too) you can freopen ("/dev/tty", "a", stdout). Is this what you were trying to do?

Redirect both cout and stdout to a string in C++ for Unit Testing

std::stringstream may be what you're looking for.

UPDATE
Alright, this is a bit of hack, but maybe you could do this to grab the printf output:

char huge_string_buf[MASSIVE_SIZE];
freopen("NUL", "a", stdout);
setbuf(stdout, huge_string_buffer);

Note you should use "/dev/null" for linux instead of "NUL". That will rapidly start to fill up huge_string_buffer. If you want to be able to continue redirecting output after the buffer is full you'll have to call fflush(), otherwise it will throw an error. See std::setbuf for more info.



Related Topics



Leave a reply



Submit