outputting debug info

N

Nick Forrington

Hi, I'm making a program and have a static Console class that I'm using
to output things, these get sent to the console and also to the graphics
on screen (I'm using SDL). One thing I'm having a bit of trouble with is
passing strings and numbers in the same arguement

e.g.

Console::println("X=" + x);

kind of thing?

anyone suggest a good solution? the only way I can seem to do it now is
by creating a string and doing something like

string s = "X=";
s += x;

This obviously gets more messy, but I'll have to stick with it if noone
has a better idea.

Thanks
Nick
 
V

Victor Bazarov

Nick Forrington said:
Hi, I'm making a program and have a static Console class that I'm using to
output things, these get sent to the console and also to the graphics on
screen (I'm using SDL). One thing I'm having a bit of trouble with is
passing strings and numbers in the same arguement

e.g.

Console::println("X=" + x);

kind of thing?

"X=" has type 'const char[3]'. Adding anything to it causes conversion
of that array to a pointer to const char. Pointers accept only values
of type 'ptrdiff_t' to be added to them. How is "x" declared? Another
pointer? Then you cannot do that. There is a simple work-around:

Console::println(string("X=") + x);
anyone suggest a good solution? the only way I can seem to do it now is by
creating a string and doing something like

string s = "X=";
s += x;

This obviously gets more messy, but I'll have to stick with it if noone
has a better idea.

You could overload 'println' to accept more than one argument...

V
 
N

Nick Forrington

Victor said:
Nick Forrington said:
Hi, I'm making a program and have a static Console class that I'm using to
output things, these get sent to the console and also to the graphics on
screen (I'm using SDL). One thing I'm having a bit of trouble with is
passing strings and numbers in the same arguement

e.g.

Console::println("X=" + x);

kind of thing?


"X=" has type 'const char[3]'. Adding anything to it causes conversion
of that array to a pointer to const char. Pointers accept only values
of type 'ptrdiff_t' to be added to them. How is "x" declared? Another
pointer? Then you cannot do that. There is a simple work-around:

Console::println(string("X=") + x);

anyone suggest a good solution? the only way I can seem to do it now is by
creating a string and doing something like

string s = "X=";
s += x;

This obviously gets more messy, but I'll have to stick with it if noone
has a better idea.


You could overload 'println' to accept more than one argument...

V
Thanks for the help. So is

Console::error(string("File ") + string(filename) + " does not exist");

the tidiest way to do that?

Also I just tried something similar when trying to output a double, and
I'm either doing something stupid (which is entirely possible) or you
can't convert a double to a string?

Any ideas?
Nick
 
V

Victor Bazarov

Nick Forrington said:
Victor said:
Nick Forrington said:
Hi, I'm making a program and have a static Console class that I'm using
to output things, these get sent to the console and also to the graphics
on screen (I'm using SDL). One thing I'm having a bit of trouble with is
passing strings and numbers in the same arguement

e.g.

Console::println("X=" + x);

kind of thing?


"X=" has type 'const char[3]'. Adding anything to it causes conversion
of that array to a pointer to const char. Pointers accept only values
of type 'ptrdiff_t' to be added to them. How is "x" declared? Another
pointer? Then you cannot do that. There is a simple work-around:

Console::println(string("X=") + x);

anyone suggest a good solution? the only way I can seem to do it now is
by creating a string and doing something like

string s = "X=";
s += x;

This obviously gets more messy, but I'll have to stick with it if noone
has a better idea.


You could overload 'println' to accept more than one argument...

V
Thanks for the help. So is

Console::error(string("File ") + string(filename) + " does not exist");

the tidiest way to do that?

Actually, you don't need the second 'string'. Once the first literal is
converted into a temporary string, you can keep "adding" literals to it.

As to that way being the tidiest, I don't know.
Also I just tried something similar when trying to output a double, and
I'm either doing something stupid (which is entirely possible) or you
can't convert a double to a string?

*I* can. <g>

Of course, you can't expect to do it using the straight + operator.
You need a function to convert the 'double' to a string first. See
http://groups.google.com/ for the 'toString' template. Then use it
like this:

double d = 3.1415926;
Console::error(string("Pi is ") + toString(d));

V
 
D

David Harmon

On Thu, 18 Nov 2004 03:09:36 +0000 in comp.lang.c++, Nick Forrington
Thanks for the help. So is

Console::error(string("File ") + string(filename) + " does not exist");

the tidiest way to do that?

std::perror(filename);
 
J

Jason Heyes

Nick Forrington said:
Hi, I'm making a program and have a static Console class that I'm using to
output things, these get sent to the console and also to the graphics on
screen (I'm using SDL). One thing I'm having a bit of trouble with is
passing strings and numbers in the same arguement

e.g.

Console::println("X=" + x);

kind of thing?

anyone suggest a good solution? the only way I can seem to do it now is by
creating a string and doing something like

string s = "X=";
s += x;

This obviously gets more messy, but I'll have to stick with it if noone
has a better idea.

Thanks
Nick

How about you make Console extend std::eek:stringstream? This way a Console
object behaves much like std::cout. You can write code like this:

console << "X = " << x << std::endl;

This is what I do in my own graphics application. Its a life saver when
debugging code.
 
J

John Harrison

Nick Forrington said:
Hi, I'm making a program and have a static Console class that I'm using to
output things, these get sent to the console and also to the graphics on
screen (I'm using SDL). One thing I'm having a bit of trouble with is
passing strings and numbers in the same arguement

e.g.

Console::println("X=" + x);

kind of thing?

anyone suggest a good solution? the only way I can seem to do it now is by
creating a string and doing something like

string s = "X=";
s += x;

This obviously gets more messy, but I'll have to stick with it if noone
has a better idea.

You need to make a stream buffer class. Then you can write

ConsoleBuffer the_console_buffer;
std::eek:stream the_console(&the_console_buffer);

the_console << "X=" << x;

Creating stream classes is a very useful thing to know how to do,
unfortunately it would take to long to explain this is a newsgroup post. But
here's a hint for your own research, you do not need to inherit from
std::eek:stream, you need to inherit from std::streambuf. In the code above
ConsoleBuffer inherits from std::streambuf.

Try googling for information on this.

john
 
I

Ivan Vecerina

Nick Forrington said:
Hi, I'm making a program and have a static Console class that I'm using to
output things, these get sent to the console and also to the graphics on
screen (I'm using SDL). One thing I'm having a bit of trouble with is
passing strings and numbers in the same arguement

e.g.

Console::println("X=" + x);

kind of thing?

anyone suggest a good solution? the only way I can seem to do it now is by
creating a string and doing something like

string s = "X=";
s += x;

This obviously gets more messy, but I'll have to stick with it if noone
has a better idea.

First of all, the C++ standard library already has built-in output
streams for writing debugging information: cerr, clog, or even cout.
These outputs can be redirected to a file or a console window using
OS facilities.
In your program, you can also replace the 'stream buffer' behind any
of these logging outputs, and transmit the data to the destination of
your choice. ( using the rdbuf() method)
See this example for redirection to a file:
http://groups.google.com/[email protected]
For other output destinations, you need to implement a custom subclass
of std::stream_buf. Dietmar Kühl, an expert on this topic, has a couple
examples available on his website: (see GUI window)
http://www.informatik.uni-konstanz.de/~kuehl/
Of course you don't *have* to reuse cout, you can also create another
ostream instance for your custom streambuf.

If you only want to generate formatted strings and use 'println' as above,
I would recomment taking a look at the excellent, free, peer_reviewed
boost::format library: http://www.boost.org/libs/format/index.html
This is a safe and flexible solution.
It might well be the best/easiest option for what you are wanting to do.

Take also a look at boost's lexical_cast, a 2-way superset of Victor's
"toString": http://www.boost.org/libs/conversion/lexical_cast.htm


I will also mention two tricks that can be used, but which I
cannot recommend for any serious development:

You could use a macro hack to use stringstream on the fly.
Something like:
#include <sstream>
#define TO_STRING( output ) \
static_cast<std::eek:stringstream&>( \
std::eek:stringstream() << "" << output \
).str().c_str();
You can then write:
Console::println(TO_STRING( "pi is" << 3.1416 << " !");


Another alternative is to emulate the sprintf interface using a function
that in turn calls vsprintf to convert the string, then outputs it.
This however tends to be bug-prone (you need to use non-standard library
functions to guarantee no buffer overflow, and this has all the other
caveats of std::printf).


I hope this helps, let me know of the approach you'll choose ;)
Ivan
 
S

Stephan Br?nnimann

Nick Forrington said:
Hi, I'm making a program and have a static Console class that I'm using
to output things, these get sent to the console and also to the graphics
on screen (I'm using SDL). One thing I'm having a bit of trouble with is
passing strings and numbers in the same arguement

e.g.

Console::println("X=" + x);

kind of thing?

anyone suggest a good solution? the only way I can seem to do it now is
by creating a string and doing something like

string s = "X=";
s += x;

This obviously gets more messy, but I'll have to stick with it if noone
has a better idea.

Thanks
Nick

Why do you not provide a few output operators for Console?
Snipets (adjusted) from my logging interface:

class Console {
// ...
public:
//! Output operator for arbitrary types and objects.
template<typename T>
inline Console& operator<<(const T& t);

//! @name IO stream manipulators.
//@{
inline Console& operator<<(
std::eek:stream& (*func)(std::eek:stream&)
);
inline Console& operator<<(
std::ios& (*func)(std::ios&)
);
inline Console& operator<<(
std::ios_base& (*func)(std::ios_base&)
);
//@}
// ...
};

2 or 3 years ago I got the necessary output operators from c.l.c++.m,
I think from James Kanze (please don't blame me if I remember the
wrong name).

My logging interface also provide functions to initiate a message
(it's actually the only way how you can get a Console&):

class Console {
// ...
public:
//! Start a fatal error message.
inline Console& fatal();
//! Start an error message.
inline Console& error();
//! Start a warning.
inline Console& warn();
//! Start a normal message.
inline Console& info();
/*!
@brief Start a debugging message.

@param level Debugging level (4-7):
1 corresponds to log level 4.
*/
inline Console& debug(int level);
//! Continue a message: useful in loops.
inline Console& cont();
// ...
};

Then you just output to Console as to a std::eek:stream:

void foo(Console& console, double d)
{
console.debug(4) << "foo start with: " << d << std::endl;
}

I guess you get an idea.
The classes I'm using provide more functionality, too big to post
unless you ask for it.

Stephan Brönnimann
(e-mail address removed)
Open source rating and billing engine for communication networks.
 
N

Nick Forrington

Nick said:
Hi, I'm making a program and have a static Console class that I'm using
to output things, these get sent to the console and also to the graphics
on screen (I'm using SDL). One thing I'm having a bit of trouble with is
passing strings and numbers in the same arguement

e.g.

Console::println("X=" + x);

kind of thing?

anyone suggest a good solution? the only way I can seem to do it now is
by creating a string and doing something like

string s = "X=";
s += x;

This obviously gets more messy, but I'll have to stick with it if noone
has a better idea.

Thanks
Nick
Thanks for the help all of you.

In the end I opted to use the toString template method, as I wanted to
keep the Console methods static, also I don't really have that much time
to start learning about more complex solutions right now (it's for an
academic project). I just wanted a quick and dirty way to output some data.

Once again, thanks for the help. Much appreciated.
Nick
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,062
Latest member
OrderKetozenseACV

Latest Threads

Top