我想创建一个带有嵌入信息的字符串,一种(不是唯一的)实现方法叫做string interpolation或变量替换,即用实际值替换字符串中的占位符。
在C语言中,我会这样做:
printf("error! value was %d but I expected %d",actualValue,expectedValue)
而如果我用python编程,我会这样做:
"error! value was {0} but I expected {1}".format(actualValue,expectedValue)
这两个都是串内插的示例。
如何在C++中做到这一点?
重要注意事项:
1.我知道,如果我想将这样的消息打印到标准输出(不是字符串插值,而是打印出我想要的字符串类型),我可以使用std::cout
:
cout << "error! value was " << actualValue << " but I expected "
<< expectedValue;
我不想 print 一个字符串到stdout。我想把一个std::string
作为一个参数传递给一个函数(例如一个异常对象的构造函数)。
1.我使用的是C11,但是可移植性是一个潜在的问题,所以知道哪些方法在哪些C版本中有效,哪些方法在哪些C++版本中无效是一个优点。
编辑
1.对于我的直接使用,我并不关心性能(我正在为cryin' out loud引发一个异常!)。* 然而 *,了解各种方法的相对性能通常会非常非常有用。
1.为什么不直接使用printf本身(C++毕竟是C的超集...)?This answer讨论了一些不这样做的原因,就我所能理解的,类型安全是一个很大的原因:如果你输入%d,你输入的变量最好能转换成整数,因为这是函数判断它是什么类型的方法。使用一个编译时知道要插入的变量的实际类型的方法会安全得多。
7条答案
按热度按时间aiazj4mn1#
在C++20中,您将能够使用
std::format
。这将支持python样式格式:
已经有可用的实作:是的。
zqdjd7g92#
方法1:使用字符串流
看起来
std::stringstream
给出了一个快速解决方案:方法2:增强格式
Boost Format库也是一种可能性。使用它,您可以执行以下操作:
编辑:
方法3:变量模板参数
printf的类型安全版本似乎可以通过使用可变模板参数(技术术语,指使用无限数量模板参数的模板)来创建。
hm2xizp93#
在C++11中,可以使用
std::to_string
:它并不漂亮,但是很简单,你可以使用宏来缩小它。性能不是很好,因为你没有预先
reserve()
空间。Variadic templates可能会更快,看起来更好。这种字符串构造(而不是插值)也不利于本地化,但如果需要的话,可能会使用库。
goqiplq24#
使用您喜欢的任何内容:
1)std::字符串流
2)库文件格式:https://github.com/fmtlib/fmt
edqdpe6u5#
C++17解决方案可同时用于
std::string
和std::wstring
(在VS2019和VS2022上测试):balp4ylt6#
免责声明:
后面的代码是基于我2年前读到的一篇文章,我会尽快找到源代码并放在这里。
这是我在我的C17项目中使用的。应该与任何支持可变模板的C编译器一起工作。
用法:
类实现:
whlutmcx7#
如果您不介意使用预处理器脚本,下面是一个更简单但方便的解决方案:https://github.com/crazybie/cpp_str_interpolation。然后您可以编写如下代码:
它还支持使用类似模板引擎: