5

C# 有一个不错的静态方法

String.Format(string, params string[]);

返回具有所提供格式和值的新字符串。C ++中有等价物吗?

原因是因为我正在使用 log4cxx 并希望利用宏,例如

LOG4CXX_DEBUG( logger, expr );

它使用短路评估,因此如果未启用日志级别 DEBUG,则永远不会评估 expr。

目前,在 C++ 中,我这样做:

CString msg;
msg.Format( formatString, values... );

LOG4CXX_INFO( _logger, msg );

这违背了目的,因为我必须首先分配和格式化字符串,所以短路逻辑几乎没有效率。

尝试使用数值进行简单日志记录时也存在类似问题。这不会编译:

LOG4CXX_DEBUG( _logger, "the price is " + _some-double_);

所以我最终不得不写这样的东西:

CString asStr;
asStr.Format( "%d", _some-double_ );
LOG4CXX_DEBUG( _logger, "the price is " + asStr );

这再次违背了目的。

我根本不是 C++ 专家,所以我希望更多知识渊博的人可以提供帮助。

4

6 回答 6

9

log4cxx 接受流式参数,因此您可以编写,例如:

LOG4CXX_DEBUG( _logger, "the price is " << price );
于 2009-08-19T05:43:54.693 回答
4

您可以回退到 C 并使用 sprintf

printf(stderr,"The Error(%d) happened(%s)\n",error,errmsg(error));

Boost 还有一种格式。

// iostream with boost::format
std::cerr << boost::format("The Error(%d) happened(%s)\n") % error % errmsg(error);

如果你想走捷径

logger && (std::cerr << Stuff); // Where Stuff can be your boost::format
于 2009-08-19T05:48:10.533 回答
3

使用标准库,如果您没有某种类型的内存分配,就无法生成格式化字符串。C++string类本身没有“格式”函数,因此您必须使用stringstream对象才能将数字与文本连接起来,但这将涉及分配对象。查看 C 函数sprintf,您需要char预先分配一个数组,因为sprintf它本身不分配任何内存。

也就是说,即使存在诸如“ string::format”之类的静态函数,我怀疑您是否会比自己分配对象和操作它获得更多的速度优势stringstream,因为静态函数很可能会在后台执行相同的操作任何事件。

于 2009-08-19T05:35:14.150 回答
3

我最喜欢的内联格式化方法是使用 boost.format 库。例如:

#include <boost/format.hpp>
using namespace boost;

LOG4CXX_INFO( _logger, str(format("cheese it %i, %g") % 1234 % 1.3) );

在日志记录和宏函数中使用可变参数非常方便。

于 2009-08-19T05:49:40.313 回答
2

要么使用 boost 格式库,要么手工编码你自己的小版本(比如这里的 make_string )。

于 2009-08-19T06:30:02.137 回答
0

严格来说,这不是您所要求的,而是不同的解决方案,您的主要问题似乎是未处于调试模式时的额外工作。

你可以这样做

    #ifdef _DEBUG
    CString msg;
    msg.Format( formatString, values... );
    #endif
    LOG4CXX_INFO( _logger, msg );
于 2022-01-21T04:27:44.737 回答