将vector <int>转换为分隔字符串

thi*_*per 8 c++ string vector

正如我在这里看到的那样,有一种快速而简短的方法将向量转换为用c#中的字符分隔的字符串:

var result = string.Join(";", data); 
var result = string.Join(";", data.Select(x => x.ToString()).ToArray()); 
Run Code Online (Sandbox Code Playgroud)

我想知道在c ++中是否有同样的方法来做到这一点?

dyp*_*dyp 13

#include <sstream>
#include <string>
#include <vector>
#include <iterator>
#include <iostream>

int main()
{
    std::vector<int> data = {42, 1, 2, 3, 4, 5};

    std::ostringstream oss;
    std::copy(data.begin(), data.end(), std::ostream_iterator<int>(oss, ";"));

    std::string result( oss.str() );
    std::cout << result << "\n";
}
Run Code Online (Sandbox Code Playgroud)

NB在C++ 11中,您可以使用更通用的表单

using std::begin;
using std::end;
std::copy(begin(data), end(data), std::ostream_iterator<int>(oss, ";"));
Run Code Online (Sandbox Code Playgroud)

如果可以使用ADL,则不需要使用声明(如上例所示).


也可能,但可能效率稍低:

std::string s;
for(auto const& e : v) s += std::to_string(e) + ";";
Run Code Online (Sandbox Code Playgroud)

其可以通过被写std::accumulate<algorithm>为:

std::string s = std::accumulate(begin(v), end(v), std::string{},
    [](std::string r, int p){ return std::move(r) + std::to_string(p) + ";"; });
Run Code Online (Sandbox Code Playgroud)

(IIRC有一些消除复制的方法,可能是通过引用取lambda参数std::string& r.)


没有尾随分号的版本(感谢DietmarKühl):

std::vector<int> data = {42, 1, 2, 3, 4, 5};

std::ostringstream out;
if (!v.empty())
{
    std::copy(v.begin(), v.end() - 1, std::ostream_iterator<int>(out, ";"));
    out << v.back();
}

std::string result( out.str() );
std::cout << result << "\n";
Run Code Online (Sandbox Code Playgroud)

  • 遗憾的是,在可能不应该有的地方却出现了尾随分号。 (2认同)
  • 我在想像 `std::string s = v.empty() 这样的东西?std::string{""}: std::accumulate(v.begin() + 1, v.end(), v.front(), [](std::string const&amp; s, int i) { return s + ";" + std::to_string(i); });` (2认同)