By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,236 Members | 1,929 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,236 IT Pros & Developers. It's quick & easy.

Formating Output of std::ostream

P: n/a
Hi,

I want to format the output of a 'std::ostream', but i dont know how to
do it [in ansi-c++].

Example:
int main()
{
my_out << "Hi.\nI'am a" << " Computer.";
my_out << "Nice.";
}

Now i want to get this as output:
[TIMESTAMP] Hi.
[TIMESTAMP] I'am a Computer.
[TIMESTAMP] Nice.
Any Ideas?
Thanks
--
Johannes B.
Dec 26 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a
Johannes Barop wrote:
Hi,

I want to format the output of a 'std::ostream', but i dont know how to
do it [in ansi-c++].

Example:
int main()
{
my_out << "Hi.\nI'am a" << " Computer.";
my_out << "Nice.";
}

Now i want to get this as output:
[TIMESTAMP] Hi.
[TIMESTAMP] I'am a Computer.
[TIMESTAMP] Nice.
Any Ideas?
Thanks

Look up on dinkumware.com or elsewhere for the manipulators for <iostream>.

Greets,
--
Stephan 'hagbard' Grein, <St***********@gmail.com>
http://hagbard.ninth-art.de/
GnuPG-Key-ID: 0x08FA3507
<ESC> :wq
Dec 26 '05 #2

P: n/a
Johannes Barop wrote:
Hi,

I want to format the output of a 'std::ostream', but i dont know how to
do it [in ansi-c++].

Example:
int main()
{
my_out << "Hi.\nI'am a" << " Computer.";
my_out << "Nice.";
}

Now i want to get this as output:
[TIMESTAMP] Hi.
[TIMESTAMP] I'am a Computer.
[TIMESTAMP] Nice.


You seem to want two things here: print timestamps on each line AND at
the end of each statement. The former is easy and the latter is not.

For the new lines, you'll have to parse the output and find them
yourself.

class timestamp_out
{
public:
void print(const std::string& s)
{
// tokenize s using \n as separator
// see boost::tokenizer
// output each line preceded by a timestamp
}
};

timestamp_out& operator<<(timestamp_out& out, const std::string& s)
{
out.print(s);
return out;
}

For the statements, on top of my head, you could return a proxy from
the first operator<< and have that proxy set a flag in timestamp_out
when it is destroyed. Since this temporary will exist until the end of
the statement, it will probably work.

Jonathan

Dec 26 '05 #3

P: n/a
Jonathan Mcdougall schrieb:
Example:
int main()
{
my_out << "Hi.\nI'am a" << " Computer.";
my_out << "Nice.";
}

Now i want to get this as output:
[TIMESTAMP] Hi.
[TIMESTAMP] I'am a Computer.
[TIMESTAMP] Nice.
You seem to want two things here: print timestamps on each line AND at
the end of each statement. The former is easy and the latter is not.
Yeha. The second one is my problem :/

For the statements, on top of my head, you could return a proxy from
the first operator<< and have that proxy set a flag in timestamp_out
when it is destroyed. Since this temporary will exist until the end of
the statement, it will probably work.


Hm, can u explain it to me with more detail? I'am not that fit in C++

--
Johannes B.
Dec 26 '05 #4

P: n/a

Johannes Barop wrote:
Jonathan Mcdougall schrieb:
Example:
int main()
{
my_out << "Hi.\nI'am a" << " Computer.";
my_out << "Nice.";
}

Now i want to get this as output:
[TIMESTAMP] Hi.
[TIMESTAMP] I'am a Computer.
[TIMESTAMP] Nice.

You seem to want two things here: print timestamps on each line AND at
the end of each statement. The former is easy and the latter is not.


Yeha. The second one is my problem :/

For the statements, on top of my head, you could return a proxy from
the first operator<< and have that proxy set a flag in timestamp_out
when it is destroyed. Since this temporary will exist until the end of
the statement, it will probably work.


Hm, can u explain it to me with more detail? I'am not that fit in C++

--
Johannes B.


He wrote a fairly simple and intuitive enough to understand example to
illustrate the concept and solve your problem. If you're still puzzled,
you should read basics on operators and c++ in general. Start with
FAQ. Really.
Best,

Dec 26 '05 #5

P: n/a
Johannes Barop wrote:
Jonathan Mcdougall schrieb:
Example:
int main()
{
my_out << "Hi.\nI'am a" << " Computer.";
my_out << "Nice.";
}

Now i want to get this as output:
[TIMESTAMP] Hi.
[TIMESTAMP] I'am a Computer.
[TIMESTAMP] Nice.

You seem to want two things here: print timestamps on each line AND at
the end of each statement. The former is easy and the latter is not.


Yeha. The second one is my problem :/

For the statements, on top of my head, you could return a proxy from
the first operator<< and have that proxy set a flag in timestamp_out
when it is destroyed. Since this temporary will exist until the end of
the statement, it will probably work.


Hm, can u explain it to me with more detail? I'am not that fit in C++


When you do

out << "one" << "two";

you'll want the first operator to return a proxy.

timestamp_out_proxy operator<<(timestamp_out& out, const std::string&
s)
{
timestamp_out_proxy p(out);
p.print(s);
return p;
}

So

operator<<(out, "one")

will return the proxy. Next, you'll want to define an operator<< for
the
proxy.

timestamp_out_proxy& operator<<
(timestamp_out_proxy& p, const std::string& s)
{
p.print(s);
return p;
}

Your proxy is a way to do something before the first output and after
the
last output in a single statement. That is, with

timestamp_out out;
out << "one" << "two";

a proxy will get constructed for "one" and will be destroyed after
"two"
(at the end of the statement). So you can use the constructor and
destructor of the proxy.

class timestamp_out_proxy
{
public:

// This constructor is called when outputting "one". It stores the
// stream and you'll understand copy_ later.
//
timestamp_out_proxy(timestamp_out& out)
: out_(out),
copy_(false)
{
}

// This constructor is called when the proxy is returned from the
// operator<<. Note that we return it by value so a copy may be
created.
// That means the original proxy will get destroyed and you'll get
// additional timestamps printed. You want the action to take place
at
// the destruction of the last proxy on the statement so you have to
// track copy construction.
//
timestamp_out_proxy(timestamp_out_proxy& p)
: out_(p.out_),
copy_(false)
{
p.copy_ = true;
}
// You'll see newline_ and timestamp_ later.
//
~timestamp_out_proxy()
{
if (!copy_)
{
// when a proxy is destroyed (end of a statement), you want the
// next output to be on a new line with [TIMESTAMP]
//
out_.newline_ = true;
out_.timestamp_ = true;
}
}
// This only forwards to the stream.
//
void print(const std::string& s)
{
out_.print(s);
}
private:
timestamp_out& out_;
bool copy_;
};

Now, on with the actual stream.

class timestamp_out
{
friend timestamp_out_proxy;
public:

// A trick here. At the very first output, you want to print a
timestamp
// but no new line.
//
timestamp_out()
: newline_(false),
timestamp_(true)
{
}

// Prints the string with timestamps and newlines
//
void print(const std::string& s)
{
// A newline will be printed iif a proxy object was destroyed.
if (newline_)
std::cout << "\n";

// A timestamp will be printed if
// 1) the stream was just created (very first output)
// 2) a proxy object was destroyed
if (timestamp_)
std::cout << "[TIMESTAMP] ";

// All subsequent strings will be printed as is (unless they have
// newlines in them).
newline_ = false;
timestamp_ = false;

// This will replace
// "Hi.\nI'm a"
// with
// "Hi.\n[TIMESTAMP} I'm a"
std::cout << boost::replace_all_copy(s, "\n", "\n[TIMESTAMP] ");
}

private:
// these control the *next* output
bool newline_;
bool timestamp_;
};

And finally:

int main()
{
timestamp_out out;

out << "Hi.\nI'am a" << " Computer.";
out << "Nice.";
}
Jonathan

Dec 26 '05 #6

P: n/a
puzzlecracker wrote:
Johannes Barop wrote:
Jonathan Mcdougall schrieb:
For the statements, on top of my head, you could return a proxy from
the first operator<< and have that proxy set a flag in timestamp_out
when it is destroyed. Since this temporary will exist until the end of
the statement, it will probably work.


Hm, can u explain it to me with more detail? I'am not that fit in C++

He wrote a fairly simple and intuitive enough to understand example to
illustrate the concept and solve your problem. If you're still puzzled,
you should read basics on operators and c++ in general. Start with
FAQ. Really.


Hey, I'll decide if I want to answer or not. If *you* don't, just stay
quiet.
Jonathan

Dec 26 '05 #7

P: n/a
On Mon, 26 Dec 2005 19:47:46 +0100, Johannes Barop <jo****@gmx.de>
wrote:
Hi,

I want to format the output of a 'std::ostream', but i dont know how to
do it [in ansi-c++].

Example:
int main()
{
my_out << "Hi.\nI'am a" << " Computer.";
my_out << "Nice.";
}

Now i want to get this as output:
[TIMESTAMP] Hi.
[TIMESTAMP] I'am a Computer.
[TIMESTAMP] Nice.
Any Ideas?
Thanks

If you derive a class form std::stringbuf, and override sync(), and
create a std::ostream with it, you may do anything whenever you put an
std::endl on the stream.

I have done exactly for this: writng a timestamp on every line, and it
works perfectly, but you should change your code to:

my_out << "Hi.<<std::endl<<I'am a" << " Computer."<<std::endl;
my_out << "Nice."<<std::endl;
Dec 27 '05 #8

P: n/a
Jonathan Mcdougall wrote:
Johannes Barop wrote:
Example:
int main()
{
my_out << "Hi.\nI'am a" << " Computer.";
my_out << "Nice.";
}

Now i want to get this as output:
[TIMESTAMP] Hi.
[TIMESTAMP] I'am a Computer.
[TIMESTAMP] Nice.


You seem to want two things here: print timestamps on each line AND at
the end of each statement. The former is easy and the latter is not.


Both are extremely easy to do although I would do them in two separate
classes, both filtering stream buffers:
- one breaks the lines after whatever amount of characters, possibly
taking whitespaces into account to detect where to break a line
- one injects whatever prefix is desired at the beginning of a line

Fiddling with 'std::ostream' derivates and/or classes overloading
'operator<<()' does not yield the desired results and is troublesome
at best.
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.eai-systems.com> - Efficient Artificial Intelligence
Dec 27 '05 #9

P: n/a
Dietmar Kuehl wrote:
Jonathan Mcdougall wrote:
Johannes Barop wrote:
Example:
int main()
{
my_out << "Hi.\nI'am a" << " Computer.";
my_out << "Nice.";
}

Now i want to get this as output:
[TIMESTAMP] Hi.
[TIMESTAMP] I'am a Computer.
[TIMESTAMP] Nice.
You seem to want two things here: print timestamps on each line AND at
the end of each statement. The former is easy and the latter is not.


Both are extremely easy to do although I would do them in two separate
classes, both filtering stream buffers:
- one breaks the lines after whatever amount of characters, possibly
taking whitespaces into account to detect where to break a line


The OP wanted a new line to be added at the end of a statement:

my_out << "First" << "line\nSecond" << "line";
my_out << "Third" << "line";

I don't think this is easy because there is no way for my_out to now
whether two operations are in the same statement.
- one injects whatever prefix is desired at the beginning of a line
Yes.
Fiddling with 'std::ostream' derivates and/or classes overloading
'operator<<()' does not yield the desired results and is troublesome
at best.


Would you care to give an example using stream buffers?
Jonathan

Dec 27 '05 #10

P: n/a
Jonathan Mcdougall wrote:
The OP wanted a new line to be added at the end of a statement:

my_out << "First" << "line\nSecond" << "line";
my_out << "Third" << "line";
OK, I missed this - probably because I hadn't even considered that
someone what to do something that - er - unusual. Had I noticed
that, I would have argued against doing something like this. BTW,
one reason why I may have missed the fact that he [to me suddenly]
wants to break the line at the end of the statement is that in a
German newsgroup he posted the same question asking for a break
after a certain number of characters.

I would argue against inserting newlines at the end of a statement
anyway: it is far too error prone! It is pretty common to split
existing lines into multiple statements in which case suddenly
newlines would be conjured up.
I don't think this is easy because there is no way for my_out to now
whether two operations are in the same statement.


Yes. The only way to do something like this using an appropriate
temporary which inserts a newline when it gets destructed. However,
as stated before, I would not combine statements with newlines or
I would make the situations at least pretty obvious, e.g. by using
a corresponding temporary. I think it is doable silently with a
class using appropriate conversions but it would be a kludge.
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.eai-systems.com> - Efficient Artificial Intelligence
Dec 27 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.