printing out data to many different files

Pages: 12
Hallo, I'm a total newbie in the C++ world. Started to learn it a month ago.
So far I've been using Fortran, where to print out some data to many different output files it was enough to create a function that would do exactly that.
1
2
3
4
5
function printtofiles(data)
write(1,*) data
write(2,*) data
write(3,*) data
end function

I know that in C++ I can do the same, but since I decided to write the code in an object oriented language, I wanted to start using classes and operators and all those goodies that C++ comes with. Here is what I have in mind.

I wanted to create a class and an operator like << so that having in the code
printtofiles << "some text";
would do exactly that, just like
cout << "some text"
prints out "some text" to the screen.
Yes I have, and I know how to write to files with <fstream> library. I don't know how to make such a class. I'm guessing that it has be derived from this class but I don't know how to do that.
Use a container of ofstream.
You may want to templatize the operator<<
I'm not sure if I understand. Does this has something to do with STL library?
ne555 could you be more specific.
1
2
3
4
5
6
7
ofstream file1("file1", ios::out);
ofstream file2("file2", ios::out);
ofstream file3("file3", ios::out);

file1 << "some text";
file2 << "some more text";
file3 << "even more text";


Is that what you're after?
Last edited on
To be specific.
I would like to put what Moschops wrote into a function and this function into a class.
1
2
3
4
5
6
7
8
9
10
11
12
13
class write{
public:
void print()
{
ofstream file1("file1", ios::out);
ofstream file2("file2", ios::out);
ofstream file3("file3", ios::out);

file1 << "some text";
file2 << "some more text";
file3 << "even more text";
}
} printtofiles;

and than to create an operator <<
So that after writing
printtofiles << data;
this function is executed.
Last edited on
So instead of a function something like this:

writeToFiles(data);
you want
writeToFiles << data; ?
Yes, that is exactly what I want.
This is proably something similar to what you want.
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
37
38
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

struct writeOut
{
  std::ofstream file1;
  std::ofstream file2;
  std::ofstream file3;

  writeOut();
  writeOut(const std::string& _1, const std::string& _2, const std::string& _3)
  {
    file1.open(_1.c_str());
    file2.open(_2.c_str());
    file3.open(_3.c_str());
  }

  friend writeOut& operator << (writeOut& out, const std::string& str);
};

writeOut& operator << (writeOut& out, const std::string& str)
{
  out.file1 << str;
  out.file2 << str;
  out.file3 << str;

  return out;
}

int main()
{
  writeOut writetofiles("file1.txt", "file2.txt", "file3.txt");
  writetofiles << "Sample Text" << " Trial";
  return 0;
}
OK, this is close. But what if I want to printout some data not a string. I know I can first place everything in a string and then use that. But a more convenient way to use it would be to
writetofiles << "Sample text" << variable << 18274 << endl;
And this is what I'm after.
You'd have to overload the << operator like this:
writeOut& operator << (writeOut& out, const std::string& str)
For everything else you want to print out instead of std::string. I'd suggest you to overload the << operator for builtin types and std::string.
Theoretically you could also do it for an own type that you could call WTF_Printable or something like that. That would be an abstract class that only has the abstract function toString(), so it would look like that:
1
2
3
4
5
class WTF_Printable
{
public:
virtual std::string& toString() = 0;
}


Other printable datatypes would have to inherit that type and implement toString to become printable.

(Though I personally think that's pretty pointless- if the class already implements toString, you could just call toString() and pass the string to the function, without needing to worry about implementing an interface).
Last edited on
Overloading << operator for builtin types works. But how to overload this operator to use it with standard manipulators like endl or fixed or scientific, so that I could format my output stream.
I'd like this class to have similar functionality that cout does.
Last edited on
For that you'd have to look at how the << operators in the STL stream classes work. I think they were just function pointers, so you'd have to overload the << operator to accept function pointers (of parameterless functions, functions with parameters must be done otherwise)

http://www.newty.de/fpt/index.html

Oh and of course std::endl and so on won't work because they expect stream objects. You'd have to define your own manipulators.
Last edited on
Sorry about the delay.
1
2
3
4
5
6
7
8
template<template<class> class container>
class writeOut{
private:
	container<std::ofstream *> output; //any container (vector, list, set, array, ... )

public:
  template<class T>
  writeOut& operator<<(const T&);
Anything that could print to an stream (like cout) will work thanks to the template. Still figuring about manipulators.

Edit: I change container<std::ofstream> to container<std::ofstream *> because ofstream does not provide a copy constructor
Last edited on
Thanks to hanst99, I think this could work for manipulators
1
2
typedef std::ostream& (*manip) ( std::ostream& os );
writeOut& operator<<( manip m);
Actually, you'd have to replace std::ostream with whatever class or struct you're using. You can't pass an ostream to your functions there, and you can't really work with the returned ostream either.
Last edited on
Sorry, I don't see it.
ostream& endl ( ostream& os ); That is how endl is declared (and I'm assuming that the others manipulators too).
The function recieves a manipulator and returns a reference to a writeOut.
The typedef is just syntactic sugar

Edit: that manipulator will be applied to every ofstream in the container.
Last edited on
Yeah, I'm stupid. I kinda messed my brain up with that one. (Not too hard at 2am).
How shall I use it (the template written by ne555)? I am trying, but I still get lots of errors compiling the code.
Last edited on
Pages: 12