Reputation:
C# has a nice static method
String.Format(string, params string[]);
that returns a new string with the formatting and values that are provided. Is there an equivalent in C++?
The reason is because I'm using log4cxx and want to take advantage of the macros like
LOG4CXX_DEBUG( logger, expr );
that uses short-circuit evaluation so that expr is never evaluated if the log level DEBUG is not enabled.
Currently, in C++, I do it like this:
CString msg;
msg.Format( formatString, values... );
LOG4CXX_INFO( _logger, msg );
which is defeating the purpose since I have to allocate and format the string first so there isn't nearly as efficiency coming out of the short-circuit logic.
There's a similar problem when trying to do simple logging with numerical values. This, won't compile:
LOG4CXX_DEBUG( _logger, "the price is " + _some-double_);
So I end up having to write something like this:
CString asStr;
asStr.Format( "%d", _some-double_ );
LOG4CXX_DEBUG( _logger, "the price is " + asStr );
which again defeats the purpose.
I'm not at all a C++ expert so I'm hoping more knowledgeable people can help.
Upvotes: 5
Views: 8315
Reputation: 2075
If you are using Microsoft CString
class, you probably want to use this helper:
CString FormatV(LPCTSTR pszFormat, ...);
CString FormatV(LPCTSTR pszFormat, ...)
{
ASSERT(pszFormat != NULL);
va_list args;
va_start(args, pszFormat);
CString str;
str.FormatV(pszFormat, args);
va_end(args);
return str;
}
LOG4CXX_DEBUG( _logger, FormatV("the price is %d", price));
For standard strings, there is std::format since C++20.
Upvotes: 0
Reputation: 49
This is not strictly what you asked but a different solution, your main problem appeared to be the extra work when not in debug mode.
You could just do this
#ifdef _DEBUG
CString msg;
msg.Format( formatString, values... );
#endif
LOG4CXX_INFO( _logger, msg );
Upvotes: 0
Reputation: 208456
Either use the boost format library or else handcode your own little version (like make_string here).
Upvotes: 2
Reputation: 4476
My favorite way to do inline formating is with the boost.format library. For example:
#include <boost/format.hpp>
using namespace boost;
LOG4CXX_INFO( _logger, str(format("cheese it %i, %g") % 1234 % 1.3) );
It's very handy for using variable arguments in logging and macro functions.
Upvotes: 3
Reputation: 264709
You can fall back to C and use sprintf
printf(stderr,"The Error(%d) happened(%s)\n",error,errmsg(error));
Boost also has a format.
// iostream with boost::format
std::cerr << boost::format("The Error(%d) happened(%s)\n") % error % errmsg(error);
If you want to shortcut
logger && (std::cerr << Stuff); // Where Stuff can be your boost::format
Upvotes: 4
Reputation: 4436
log4cxx accepts stream like parameters, so you can write, for example:
LOG4CXX_DEBUG( _logger, "the price is " << price );
Upvotes: 9
Reputation: 4022
Using the standard libraries, there is no way to produce a formatted string without some type of memory allocation on your part. The C++ string
class does not have a "format" function per se, so you must use a stringstream
object in order to concatenate numbers with text, but that would involve allocating the object. Looking at C functions like sprintf
, you need to allocate a char
array beforehand since sprintf
does not allocate any memory itself.
That said, even if there existed a static function such as "string::format
" I doubt you would get much of a speed advantage over allocating a stringstream
object yourself and manipulating it, given that the static function would most likely be doing the same things in the background in any event.
Upvotes: 3