C++ ostream formatting

1.2k views Asked by At

I want to get a C++ class Xyz such that the following:

Xyz mything("/tmp/x1");

int main(int argc, char **argv) {
    mything << "Hello world";
}

causes a file "/tmp/x1" to be created, and the following

2013-12-04 12:01 :: Hello world

to be written to it.

The first issue I have is that ostream has many specialised methods for each type that may follow the <<. The second is that if I have

cout << "hello" << "world";

and

cout << "hello";

then the implementation for operator << called for "hello" needs to know whether anything follows it in the statement (how do I effectively do an if(last_in_line_of_<<) type construct?). The standard cout does this by having objects like endl.

Basically I want to create a global log object with a single line, once the class has been defined, and to write to it with ostream operations such that the string that, say, cout would get would be wrapped in a larger string.

I've ended up looking at this way of doing it since the varargs way is painful and many people seem to recommend against it.

In scripting languages like Python and Ruby, objects have a str or to_s method (or equivalent) and print and format call these to format them, so that "hello {} world".format(x) formats one parameter, and "hello {} world".format(" ".join(x)) joins a list, after formatting to strings, with spaces and then sticks that into the resulting string.

I'm wondering what the right C++ way is to do this.

2

There are 2 answers

0
Emilio Garavaglia On

Instad to giving to Xyz a stream behavior, make it a manipulator and use normal streams facilities:

A function prototyped as

std::ostream& logtime(std::ostream& s)
{
   /* write date and time to s */
   return s;
}

can be used as

std::cout << logtime << "text and other things" << std::endl;

if std::cout is replaced by whatever other ostream (like a outfile variable of type std::filestream) you get exactly that effect, but using a manipulator that can work with whatever type of output stream (non necessarily a file)

std::ofstream outfile("file");
outfile << logtime << "text and whatever else" << std::endl;
0
DavidRR On

To learn how to format your output, see iomanip in the Standard C++ Library reference at cplusplus.com.

For example:

  • setfill -- Set fill character
  • setprecision -- Set decimal precision
  • setw -- Set field width