How to pass a cout-style stream into a function.

I'm trying to write a logging function that multiple users can use in their functions with minimal effort (1 line required, no extra variables). Forgive me if I am completely out to lunch here. I'm still learning. I tried the Beginner forum but got no responses. Does anyone have any tips?

It needs to be able to take anything they may want to output in a cout-type style (stings and variables mixed). I'd also like to be able to add a short mask that will give me options (like colour, or outputing to a file).

Essentially I need to turn the following macro into a function (where fout is an ofstream object).

1
2
3
4
#define LOGOUT(w,m) { \
  if (m & 0xf0) fout << w << endl << flush; \
  if (m & 0x0f) cout << w << endl; \
} 


My problem is, how can I pass a stream through to a function? I've tried using a stringstream as a way of passing this and haven't been able to get it to work.
I can see why it doesn't work but can't figure out what will work.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream.h>
#include <fstream.h>
#include <sstream.h>

ofstream fout("output.txt");
stringstream ss (stringstream::in | stringstream::out);

void logout(stringstream message, short mask)
{
  if (mask & 0xf0) fout << message << endl << flush;
  if (mask & 0x0f) cout << message << endl;
}
int main()
{
  int i = 1;
  logout (ss << "outputs message 1 to console"         , 0x0f);
  logout (ss << "outputs message " << ++i << " to file", 0xf0);
  logout (ss << "outputs message 3 to file and console", 0xff);
  return 0;
}


Your LOGOUT macro doesn't take a stream, so why you want to take a stream now?

In any case:

void logout(ostream &out, ...) //BTW, logout() is a very unfortunate name for a logging function.
Ahh so something like this might work then:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream.h>
#include <fstream.h>

ofstream fout("output.txt");
ostream LogMe;

void logger(ostream &message, short mask)
{
  if (mask & 0xf0) fout << message << endl << flush;
  if (mask & 0x0f) cout << message << endl;
}
int main()
{
  int i = 1;
  logger (LogMe << "outputs message 1 to console"         , 0x0f);
  logger (LogMe << "outputs message " << ++i << " to file", 0xf0);
  logger (LogMe << "outputs message 3 to file and console", 0xff);
  return 0;
}


This is the simple solution I was hoping for. I'll give it a try, thanks!
Oh and the reason why I didn't like the macro was that is wasn't safe in the event that I used something like ++i in the input.
If you have studied classes, you should create a Logger class, not a Logger function. The logger class can then have a configurable filename, for example, that gets passed to the object in the constructor:

Logger log = "myLogFile.txt";

As for your code above, AFAIK the ostream data type (class) is an abstract one, meaning you cannot create objects of this type. You must create objects of derived types, like ofstream, stringstream and the like.
Topic archived. No new replies allowed.