printing out data to many different files

Pages: 12
writeOut<std::vector> Out; However if you prefer just get rid of the template and use vector.

Also, I make a big mistake. ofstream has a private copy constructor so the container should be of pointers instead. container <std::ofstream *> output;

Be awared that you will need to implement a proper destructor, copy constructor and assignment operator (you could avoid the last two by making private as in ofstream)
Last edited on
A much simpler solution: use tee (linux)
./program.bin | tee file1 file2 file3 ... [ > /dev/null]

Now to implement tee (simplified version)
1
2
3
4
5
6
7
8
int main(int argc, int *argv[]){
  /*creation of the files*/

  while( cin.read( buffer, size ) )
    for( int K=1; K<argc; K++)
      file[K].write( buffer, size );

}
How do I make this work with templates? I'm trying to do what ne555 wrote but I can't figure it out.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <fstream>
#include <vector>
#include <iomanip>

namespace out{
	class Output{
	private:
		std::vector<std::ofstream *> out; //lack of copy constructor for ofstream (an auto_ptr could be used)
		Output(const Output &); //I don't know what they are supposed to do so I keep them private
		Output& operator=(const Output &); //to avoid implement them
	public:
		Output();
		~Output(); //need to handle the allocated memory
		template <class T>
		Output& operator<<(const T &obj); //objects
		typedef std::ostream& (*manip) (std::ostream&);
		Output& operator<<(manip m); //manipulators (however I don't understand the need of the specialization, 
								//the code is the same as the one with the template

		void add(const char *filename){
			out.push_back( new std::ofstream(filename) );
		}
	};
}

int main(){
	out::Output salida;
	salida.add( "hello.txt" );
	salida.add( "world.txt" );
	salida.add( "another.txt" );
	salida.add( "/dev/stdout" ); //linux
	salida << "hello " << 42 << ' ' << std::setprecision(5) << std::fixed << 3.14;
	salida << std::endl;
	return 0;
}
That's what I used.
What problems do you have? Post your code.
I can't figure out what is wrong
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Output{
private:
   int nout;
   std::vector<std::ofstream *> out;
   Output(const Output &);
   Output& operator=(const Output &);
public:
   Output() {nout=0;}
   ~Output() {}
   template <class T>
   Output& operator<<(const T &obj)
   {
      for (int i=0; i<nout; i++) out[i] << obj;
      return out;
   }
   typedef std::ostream& (*manip) (std::ostream&);
   Output& operator<<(manip m)
   {
   for (int i=0; i<nout; i++) out[i] << m;
   return out;
   }
		
   void add(const char *filename){
   out.push_back( new std::ofstream(filename) );
   nout++;
   }
};

Last edited on
1
2
3
std::vector<std::ofstream *> out; //a vector of pointers
out[i]; //returns a pointer
(*out[i]) << obj; //you need to dereference the pointer 

Also there is no need for the nout variable, the vectors keep track of their size. out.size();

1
2
3
4
5
6
Output& operator<<(const T &obj) //this function returns a reference to an Output
   {
      for (int i=0; i<nout; i++) out[i] << obj;
//      return out; //out is a vector, not an Output
      return *this;
   }


Post the compiler errors.
Now it works, thank you very much!

What if I want to print something out to only one of those files? (Some of the data goes to all the files and some only to particular file.)
Does moving std::vector<std::ofstream *> out; from private to public is a good idea? I can call the function *salida.out[1] << "something" << std::endl;, and then everything works. Is this the way to do this? Perhaps there is a more elegant way. I'm asking because I'm curious.
Last edited on
Topic archived. No new replies allowed.
Pages: 12