Click here to Skip to main content
15,914,608 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a function that prints large amount of information to the console as well as to a file.

As such, it looks something like this:

void display()
{

ofstream fout;
fout.open("D:\\Output.txt");

cout << "Value of x="<<x<<endl;
cout << "Value of y="<<y<<endl;
cout << "Value of z="<<z<<endl;

fout << "Value of x="<<x<<endl;
fout << "Value of y="<<y<<endl;
fout << "Value of z="<<z<<endl;
}


The problem is, I have to repeat all the cout lines to fout for the same lines to be printed in console as well as file. Can we have a function something like this:

void display(param)
{
param << "Value of x="<<x<<endl;
param << "Value of y="<<y<<endl;
papam << "Value of z="<<z<<endl;
}

and then call this function twice with cout and fout arguements:
display(cout);
display(fout);


so that the code looks far less clumsy..

please help me out...
Posted
Updated 9-Jan-11 9:20am
v2

I think that it would be better if, rather than passing the output device to your Display function, pass it the output string.

So your Display would then look more like

C++
void Display(param)
{
  cout << param<<endl;
  fout << param<<endl;
}
 
Share this answer
 
Comments
Dalek Dave 9-Jan-11 17:36pm    
Excellent answer.
If you want to maintain the same interface, you can make a fake stream (a class that support the << operator like a stream) that redirect the output.

Something like
C++
class dupstream
{
    std::ostream *s1, *s2;
    dupstream(comnst dupstream&);
    dupstream& operator=(comnst dupstream&);
public:
    dupstream(std::ostream& a, std::ostream& b)
        :s1(&a), s2(&b)
    {}
    template<class T>
    friend dupstream& operator<<(dupstream& s, const T& a)
    {
        *s1 << a;
        *s2 << a;
        return s;
    }
};

and then use it as
C++
ofstream fout;
fout.open("D:\\Output.txt");
dupstream(std::cout, fout);

dupstream << "Value of x="<<x<<endl;
dupstream << "Value of y="<<y<<endl;
dupstream << "Value of z="<<z<<endl;
 
Share this answer
 
Comments
Aescleal 10-Jan-11 15:25pm    
I'd suggest writing a streambuf to do the sort of thing you're advocating there. While an isolated class like yours would work you couldn't use it in place of other streams. Which may or may not be a problem elsewhere, depending on how much you use streams.
Emilio Garavaglia 11-Jan-11 1:51am    
"I'd suggest writing a streambuf ..." Tecnically perfect, but consider the OP starting point! writing a streambuf my be not as easy if you don't have a good knowledge of its interface and on how it is called by a stream. And -as far my experience is- there is almost no clear documentation on it (apart the streambuf description, I mean. You can find good books and articles on STL and iostream, but they tend to show the classes as black-boxes, giving no idea about the ARCHITECTURE. They just describe the "pieces")
If you want to pass an output stream as function argument you could do that like so:

void myfunction(ostream& outs)
{
	outs << "hello";
}


Henry Minute's way seems like the nicer solution however.
 
Share this answer
 
v2
The simple answer is to use a unix tee like utlility for windows.

The tee command reads standard input, then writes its content to standard output and simultaneously copies it into the specified file.

Here is one with source code:
http://www.chipstips.com/?p=129[^]

Regards
Espen Harlinn
 
Share this answer
 
Thanks for your replies. Here is the code I've rewritten:
#include<iostream>
#include<fstream>
#include<conio.h>

using namespace std;
void display( std::ostream & output_to )
{
    output_to << "I'm some output" << std::endl;

    // Add more lines to taste...
}
int main()
{
	ofstream fout;
	fout.open("D:\\sampleout.txt");

	display(cout);
	dispaly(fout);

	_getch();
}


and that shows a compile error(VC++ 2008 Express Edition) error C3861: 'dispaly': identifier not found.
 
Share this answer
 
Comments
[no name] 10-Jan-11 4:37am    
Your function is called display and you call dispaly (notice the spelling).
AshisKumar123 10-Jan-11 13:39pm    
Thanks a lot :)
Turning the question around a bit, what's common between std::cout and an arbitrary std::ofstream?

If you have a look at the documentation for both you'll see that they're instances of classes derived from std::ostream. In your examples all the operations you do are members of std::ostream so yep, there is a parameter type you can use which will do what you want - a reference to a std::ostream. So you could write:

void display_some_guff( std::ostream &output_to )
{
    output_to << "I'm some output" << std::endl;

    // Add more lines to taste...
}


and then feed the function either std::cout or a std::ofstream.

So now you know how (okay, you know one way) to abstract out the thing you want to do the output to. However are you sure you're concentrating on abstracting out the right thing? If what you were interested in displaying was neatly parceled up in an object your code becomes:

std::cout   << prog_state << std::endl;
file_stream << prog_state << std::endl;


and the whole question goes away or becomes a lot less pressing as you've solved it as a direct consequence of your object model.

Cheers,

Ash
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900