C++内联字符串格式化和数字转换

发布于 2024-08-03 03:08:31 字数 787 浏览 8 评论 0原文

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++ 专家,所以我希望更多知识渊博的人可以提供帮助。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

提赋 2024-08-10 03:08:31

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

LOG4CXX_DEBUG( _logger, "the price is " << price );

log4cxx accepts stream like parameters, so you can write, for example:

LOG4CXX_DEBUG( _logger, "the price is " << price );
莳間冲淡了誓言ζ 2024-08-10 03:08:31

您可以退回到 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

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
溺孤伤于心 2024-08-10 03:08:31

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

也就是说,即使存在诸如“string::format”之类的静态函数,我怀疑与自己分配 stringstream 对象并操作相比,您是否会获得很大的速度优势考虑到静态函数很可能在任何情况下都在后台执行相同的操作。

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.

若无相欠,怎会相见 2024-08-10 03:08:31

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

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

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

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

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.

ぶ宁プ宁ぶ 2024-08-10 03:08:31

要么使用 boost 格式库,要么手动编码您自己的小版本(例如 make_string

Either use the boost format library or else handcode your own little version (like make_string here).

源来凯始玺欢你 2024-08-10 03:08:31

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

你可以这样做

    #ifdef _DEBUG
    CString msg;
    msg.Format( formatString, values... );
    #endif
    LOG4CXX_INFO( _logger, msg );

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 );
森林很绿却致人迷途 2024-08-10 03:08:31

如果您使用 Microsoft CString 类,您可能需要使用此帮助器:

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));

对于标准字符串,自 C++20 起就有 std::format。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文