Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assigning cout to a variable name

Tags:

c++

ofstream

cout

In ANSI C++, how can I assign the cout stream to a variable name? What I want to do is, if the user has specified an output file name, I send output there, otherwise, send it to the screen. So something like:

ofstream outFile;
if (outFileRequested) 
    outFile.open("foo.txt", ios::out);
else
    outFile = cout;  // Will not compile because outFile does not have an 
                     // assignment operator

outFile << "whatever" << endl;

I tried doing this as a Macro function as well:

#define OUTPUT outFileRequested?outFile:cout

OUTPUT << "whatever" << endl;

But that gave me a compiler error as well.

I supposed I could either use an IF-THEN block for every output, but I'd like to avoid that if I could. Any ideas?

like image 988
user12576 Avatar asked Jan 09 '09 16:01

user12576


People also ask

How do you display a variable name in C++?

There is no way to enumerate members of the class in C++, since there is no reflection in C++. So you cannot have access to the variable name. Save this answer.

Is cout a variable?

cout is an instance of the class std::ostream , and yes, it's a global variable.

How do you change the name of a variable in C++?

To rename a variable or function: In the Code Editor, open the needed script unit and locate the line where the variable or function is declared. Right-click the variable or function name and then click Rename.


2 Answers

Use a reference. Note that the reference must be of type std::ostream, not std::ofstream, since std::cout is an std::ostream, so you must use the least common denominator.

std::ofstream realOutFile;

if(outFileRequested)
    realOutFile.open("foo.txt", std::ios::out);

std::ostream & outFile = (outFileRequested ? realOutFile : std::cout);
like image 199
Adam Rosenfield Avatar answered Oct 02 '22 00:10

Adam Rosenfield


I assume your program behaves like standard unix tools, that when not given a file will write to standard output, and when given a file will write into that file. You can redirect cout to write into another stream buffer. As long as your redirection is alive, everything written to cout is transparently written to the destination you designated. Once the redirection object goes out of scope, the original stream is put and output will write to the screen again:

struct CoutRedirect { 
    std::streambuf * old; 
    CoutRedirect():old(0) {
        // empty
    }

    ~CoutRedirect() {
        if(old != 0) {
            std::cout.rdbuf(old);
        }
    }

    void redirect(std::streambuf * to) {
        old = std::cout.rdbuf(to);
    }
}

int main() {
    std::filebuf file;
    CoutRedirect pipe;
    if(outFileRequested) {
        file.open("foo.txt", std::ios_base::out);
        pipe.redirect(&file);
    }
}

Now, cout is redirected to the file as long as the pipe is alive in main. You can make it more "production ready" by making it non-copyable, because it's not ready to be copied: If the copy goes out of scope, it would restore the original stream already.

like image 34
Johannes Schaub - litb Avatar answered Oct 02 '22 01:10

Johannes Schaub - litb