C++中快速格式化的字符串

sle*_*ica 17 c++ string formatting

在构造std :: string时是否有一种快速,简单的方法来获得类似sprintf的格式?就像是...

std::string foo("A number (%d) and a character (%c).\n", 18, 'a');
Run Code Online (Sandbox Code Playgroud)

Dou*_* T. 16

没有内置到字符串的构造函数中,但您可能想要检查boost格式.它是一种更加类型安全的sprintf样式字符串格式.有了它你至少可以这样做:

std::string foo = 
    boost::str(boost::format("A number (%d) and a character (%c)\n") % 18 % 'a');
Run Code Online (Sandbox Code Playgroud)


Naw*_*waz 11

我写了一个stringbuilder类,你可以用,我认为这是优于boost::format因为不像它,stringbuilder不使用C风格的格式字符串一样%d,%c.等等

以下是如何stringbuilder帮助您只需一行:

std::string s=stringbuilder() << "A number " << 18 <<" and a character " <<'a';
Run Code Online (Sandbox Code Playgroud)

执行stringbuilder很简单:

struct stringbuilder
{
   std::stringstream ss;
   template<typename T>
   stringbuilder & operator << (const T &data)
   {
        ss << data;
        return *this;
   }
   operator std::string() { return ss.str(); }
};
Run Code Online (Sandbox Code Playgroud)

在ideone上演示:http://ideone.com/J9ALB


我刚刚编写了以下博客,描述了许多不同的使用方式stringbuilder.

  • +1感谢分享:)但我有点像C风格的格式语法更好.我个人发现"这是我的字符串,取代了认可的标记"的方法,以形成更舒适的一块一块地组装它们. (7认同)
  • @Nawaz:假设您希望在用户选择中加入形容词.在法语中,你有句子`printf("J'ai vu des oiseaux%s",形容词);`这对于一个流很好:`os <<"J'ai vu des oiseaux"<<形容词`.然而,在英语中,"os <<"我看过鸟类"<<形容词"是不正确的.你需要`printf("我见过%s鸟",形容词)`.这句话完全不同.在这种情况下,您需要在流上进行C样式格式化.(或者您需要更改每种语言的流,但这很疯狂,请查看gettext以了解如何处理资源) (5认同)
  • @Nawaz:这也是为什么开发boost :: format的原因,它具有类似于格式的printf,并且和iostream一样安全. (4认同)
  • @Nawaz:一旦你编写了国际化的软件,你就会喜欢C格式化的风格(尽管有安全的方法......),因为它能够在最终翻译中移动动态位.IOStream支持方面,它们会让你付出沉重的代价,但它对国际化没有任何帮助:/ (3认同)

vit*_*aut 7

该FMT库提供了一个安全的sprintf实现,它返回一个字符串:

std::string foo = fmt::sprintf("A number (%d) and a character (%c).\n", 18, 'a');
Run Code Online (Sandbox Code Playgroud)

该库还支持Python的str.format语法:

std::string foo = fmt::format("A number ({}) and a character ({}).\n", 18, 'a');
Run Code Online (Sandbox Code Playgroud)

它的目的与Boost Format类似,但速度更快,非常小,并且除了标准C++库之外没有外部依赖性.

免责声明:我是这个图书馆的作者.