Freopen() Equivalent for C++ Streams

freopen() equivalent for c++ streams

freopen also works with cin and cout. No need to search for something new.

freopen("input.txt", "r", stdin); // redirects standard input
freopen("output.txt", "w", stdout); // redirects standard output

int x;
cin >> x; // reads from input.txt
cout << x << endl; // writes to output.txt

Edit: From C++ standard 27.3.1:

The object cin controls input from a stream buffer associated with the object stdin, declared in <cstdio>.

So according to the standard, if we redirect stdin it will also redirect cin. Vice versa for cout.

freopen: reverting back to original stream

This can be achieved using fileno, dup and dup2 calls. I have tried this on linux not sure whether this will work on mac but I am sure you will get some equivalent functions for your setup. See if this sample code works for you. Sorry for lack of error-handling in the code. :)

    #include <stdio.h>

main()
{
int fd;
fpos_t pos;

printf("stdout, ");

fflush(stdout);
fgetpos(stdout, &pos);
fd = dup(fileno(stdout));
freopen("stdout.out", "w", stdout);

f();

fflush(stdout);
dup2(fd, fileno(stdout));
close(fd);
clearerr(stdout);
fsetpos(stdout, &pos); /* for C9X */

printf("stdout again\n");
}

f()
{
printf("stdout in f()");
}

Using freopen() to print to file and screen

I don't know a simple way to achieve that, but I've managed to solve this somehow.

Using fstreams you can output to file the same way you can write to console.

#include <fstream>

int main()
{
std::ofstream f("file.txt");
f << "something";
}

Now there's a point we can start: is there a way we can output to the console and file simultaneously?

I've recently written stream demultiplexer to address that problem:

#include <vector>
#include <ostream>
class stream_demultiplexer
{
private:
typedef std::vector<std::ostream*> str_cont;
str_cont d;
public:
stream_demultiplexer& put(std::ostream::char_type ch)
{
for(str_cont::iterator it = d.begin(); it != d.end(); ++it)
(*it)->put(ch);
return *this;
}

stream_demultiplexer& write(const std::ostream::char_type* s, std::streamsize count)
{
for(str_cont::iterator it = d.begin(); it != d.end(); ++it)
(*it)->write(s, count);
return *this;
}

stream_demultiplexer& flush()
{
for(str_cont::iterator it = d.begin(); it != d.end(); ++it)
(*it)->flush();
return *this;
}

template<typename T>
stream_demultiplexer& operator<<( const T& obj )
{
for(str_cont::iterator it = d.begin(); it != d.end(); ++it)
(**it) << obj;
return *this;
}

stream_demultiplexer& operator<<(std::ios_base& (*func)(std::ios_base&))
{
for(str_cont::iterator it = d.begin(); it != d.end(); ++it)
(**it) << func;
return *this;
}

template<typename CharT, typename Traits>
stream_demultiplexer& operator<<(std::basic_ios<CharT,Traits>& (*func)(std::basic_ios<CharT,Traits>&) )
{
for(str_cont::iterator it = d.begin(); it != d.end(); ++it)
(**it) << func;
return *this;
}

stream_demultiplexer& operator<<(std::ostream& (*func)(std::ostream&) )
{
for(str_cont::iterator it = d.begin(); it != d.end(); ++it)
(**it) << func;
return *this;
}

void add_stream(std::ostream& ss)
{
d.push_back(&ss);
}
};

You can use it like this:

stream_demultiplexer spl;
std::ofstream f("file.txt");
spl.add_stream(f);
spl.add_stream(std::cout);
spl << 55 << " HELLO WORLD";

My approach has advantage that manipulators and unformatted output works correctly:

spl << 76 << " " << std::hex << 76 << std::endl;
spl.put('a');
spl.write("ABCDE", 5);

opening multiple files using freopen in c++

In line freopen(argv[2], "r", stdin); you are trying to reopen stdin. But you have already closed stdin in line fclose(stdin); just before that. Also, stdin is now dangling pointer after closing the file.

Following is an extract from www.cplusplus.com:

If a new filename is specified, the function first attempts to close any file already associated with stream (third parameter) and disassociates it. Then, independently of whether that stream was successfuly closed or not, freopen opens the file specified by filename and associates it with the stream just as fopen would do using the specified mode.

You should use fopen() function after closing stdin.

Equivalent of freopen in Go

You can assign to os.Stdin, os.Stdout, and os.Stderr.

import "os"

os.Stdin, err = os.OpenFile("input.txt",
os.RDONLY | os.O_CREATE, 0666)
os.Stdout, err = os.OpenFile("output.txt",
os.O_WRONLY | os.O_CREATE | os.O_TRUNC, 0666)


Related Topics



Leave a reply



Submit