C++ 如何使用参数集合格式化 std::string?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5076472/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:19:36  来源:igfitidea点击:

How can I format a std::string using a collection of arguments?

c++string-formattingstdstringvariadic-functions

提问by jilt3d

Is it possible to format std::stringpassing a set of arguments?

是否可以格式化std::string传递一组参数?

Currently I am formatting the string this way:

目前我正在以这种方式格式化字符串:

string helloString = "Hello %s and %s";
vector<string> tokens; //initialized vector of strings
const char* helloStringArr = helloString.c_str();
char output[1000];
sprintf_s(output, 1000, helloStringArr, tokens.at(0).c_str(), tokens.at(1).c_str());

But the size of the vector is determined at runtime. Is there any similar function to sprintf_swhich takes a collection of arguments and formats a std::string/char*? My development environment is MS Visual C++ 2010 Express.

但是向量的大小是在运行时确定的。是否有任何类似的函数sprintf_s接受一组参数并格式化 std::string/char*?我的开发环境是 MS Visual C++ 2010 Express。

EDIT:I would like to achieve something similar:

编辑:我想实现类似的东西:

sprintf_s(output, 1000, helloStringArr, tokens);

采纳答案by visitor

You can do it with the Boost.Formatlibrary, because you can feed the arguments one by one.

您可以使用Boost.Format库来实现,因为您可以一一提供参数。

This actually enables you to achieve your goal, quite unlike the printffamily where you have to pass all the arguments at once (i.e you'll need to manually access each item in the container).

这实际上使您能够实现您的目标,这与printf您必须一次传递所有参数的系列完全不同(即您需要手动访问容器中的每个项目)。

Example:

例子:

#include <boost/format.hpp>
#include <string>
#include <vector>
#include <iostream>
std::string format_range(const std::string& format_string, const std::vector<std::string>& args)
{
    boost::format f(format_string);
    for (std::vector<std::string>::const_iterator it = args.begin(); it != args.end(); ++it) {
        f % *it;
    }
    return f.str();
}

int main()
{
    std::string helloString = "Hello %s and %s";
    std::vector<std::string> args;
    args.push_back("Alice");
    args.push_back("Bob");
    std::cout << format_range(helloString, args) << '\n';
}

You can work from here, make it templated etc.

您可以从这里工作,使其模板化等。

Note that it throws exceptions (consult documentation) if the vector doesn't contain the exact amount of arguments. You'll need to decide how to handle those.

请注意,如果向量不包含确切数量的参数,它会抛出异常(请参阅文档)。你需要决定如何处理这些。

回答by SirDarius

The most C++-ish way to achieve sprintf-like functionality would be to use stringstreams.

实现类似 sprintf 的功能的最 C++ 风格的方法是使用stringstreams

Here is an example based on your code:

这是基于您的代码的示例:

#include <sstream>

// ...

std::stringstream ss;
std::vector<std::string> tokens;
ss << "Hello " << tokens.at(0) << " and " << tokens.at(1);

std::cout << ss.str() << std::endl;

Pretty handy, isn't it ?

很方便,不是吗?

Of course, you get the full benefit of IOStream manipulation to replace the various sprintf flags, see here http://www.fredosaurus.com/notes-cpp/io/omanipulators.htmlfor reference.

当然,您可以充分利用 IOStream 操作来替换各种 sprintf 标志,请参阅http://www.fredosaurus.com/notes-cpp/io/omanipulators.html以供参考。

A more complete example:

一个更完整的例子:

#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>

int main() {
  std::stringstream s;
  s << "coucou " << std::setw(12) << 21 << " test";

  std::cout << s.str() << std::endl;
  return 0;
}

which prints:

打印:

coucou           21 test

Edit:

编辑

As pointed by the OP, this way of doing things does not allow for variadic arguments, because there is no `template' string built beforehand allowing the stream to iterate over the vector and insert data according to placeholders.

正如 OP 所指出的那样,这种处理方式不允许使用可变参数,因为没有预先构建的“模板”字符串允许流迭代向量并根据占位符插入数据。

回答by Martin Stone

The boost::formatlibrary might be of interest if you want to avoid having to manually deal with the output buffer.

升压::格式,如果你想避免手动与输出缓冲处理库可能会感兴趣。

As for taking the plain vector as input, what would you want to happen if tokens.size()<2? Wouldn't you have to ensure that the vector was big enough to index elements 0 and 1 in any case?

至于将普通向量作为输入,如果 ,您希望发生tokens.size()<2什么?在任何情况下,您都不必确保向量足够大以索引元素 0 和 1 吗?