将vector <int>转换为字符串

dzh*_*lil 85 c++ vector tostring

我有一个vector<int>有整数的容器(例如{1,2,3,4}),我想转换为表格的字符串

"1,2,3,4"
Run Code Online (Sandbox Code Playgroud)

在C++中最干净的方法是什么?在Python中,我就是这样做的:

>>> array = [1,2,3,4]
>>> ",".join(map(str,array))
'1,2,3,4'
Run Code Online (Sandbox Code Playgroud)

Bri*_*ndy 89

绝对不如Python优雅,但没有什么比C++中的Python更优雅.

你可以使用stringstream......

#include <sstream>
//...

std::stringstream ss;
for(size_t i = 0; i < v.size(); ++i)
{
  if(i != 0)
    ss << ",";
  ss << v[i];
}
std::string s = ss.str();
Run Code Online (Sandbox Code Playgroud)

你也可以使用std::for_each.

  • 没有`#include <sstream>`,答案是不完整的 (12认同)
  • 那应该是`std :: string s = ss.str()`.如果你想要一个`const char*`,请使用`s.c_str()`.(注意,虽然语法正确,但`ss.str().c_str()`会给你一个`const char*',它指向一个临时表达式,它将在完整表达式结束时停止存在.这很痛苦. ) (2认同)

Mar*_*ork 43

使用std :: copy和std :: ostream_iterator,我们可以得到像python一样优雅的东西.

#include <iostream>
#include <sstream>

int main()
{
     int  array[] = {1,2,3,4};
     std::for_each(std::begin(array), std::end(array),
                   [&std::cout, sep=' '](int x) mutable {
                       out << sep << x; sep=',';
                   });
}
Run Code Online (Sandbox Code Playgroud)

看到这个问题,我写了一个小班.这不会打印尾随的逗号.此外,如果我们假设C++ 14将继续为我们提供基于范围的等效算法,如下所示:

namespace std {
   // I am assuming something like this in the C++14 standard
   // I have no idea if this is correct but it should be trivial to write if it  does not appear.
   template<typename C, typename I>
   void copy(C const& container, I outputIter) {copy(begin(container), end(container), outputIter);}
}
using POI = PrefexOutputIterator;   
int main()
{
     int  array[] = {1,2,3,4};
     std::copy(array, POI(std::cout, ","));
  // ",".join(map(str,array))               // closer
}
Run Code Online (Sandbox Code Playgroud)

  • 显然优雅是主观的.因此,如果你和另外两个人喜欢更长,更重复的代码不起作用,那么它会更优雅;-p (20认同)
  • 我认为这与Python的连接并不完全相同 - 它最后会插入一个额外的",". (12认同)
  • 不是等同的,但同样优雅(事实上我认为更多,但这只是一个意见). (2认同)

cap*_*one 20

你可以使用std :: accumulate.请考虑以下示例

if (v.empty() 
    return std::string();
std::string s = std::accumulate(v.begin()+1, v.end(), std::to_string(v[0]),
                     [](const std::string& a, int b){
                           return a + ',' + std::to_string(b);
                     });
Run Code Online (Sandbox Code Playgroud)

  • @Matt “string”类有一个“+”运算符的重载,它也可以接受字符。所以`','`就可以了。 (2认同)

180*_*ION 17

另一种选择是使用std::copyostream_iterator类:

#include <iterator>  // ostream_iterator
#include <sstream>   // ostringstream
#include <algorithm> // copy

std::ostringstream stream;
std::copy(array.begin(), array.end(), std::ostream_iterator<>(stream));
std::string s=stream.str();
s.erase(s.length()-1);
Run Code Online (Sandbox Code Playgroud)

也不如Python好.为此,我创建了一个join函数:

template <class T, class A>
T join(const A &begin, const A &end, const T &t)
{
  T result;
  for (A it=begin;
       it!=end;
       it++)
  {
    if (!result.empty())
      result.append(t);
    result.append(*it);
  }
  return result;
}
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:

std::string s=join(array.begin(), array.end(), std::string(","));
Run Code Online (Sandbox Code Playgroud)

你可能会问为什么我传入了迭代器.好吧,实际上我想要反转数组,所以我像这样使用它:

std::string s=join(array.rbegin(), array.rend(), std::string(","));
Run Code Online (Sandbox Code Playgroud)

理想情况下,我想模板化它可以推断出char类型,并使用字符串流,但我还是无法解决这个问题.


are*_*lek 12

使用Boost和C++ 11,可以像这样实现:

auto array = {1,2,3,4};
join(array | transformed(tostr), ",");
Run Code Online (Sandbox Code Playgroud)

好吧,差不多.这是完整的例子:

#include <array>
#include <iostream>

#include <boost/algorithm/string/join.hpp>
#include <boost/range/adaptor/transformed.hpp>

int main() {
    using boost::algorithm::join;
    using boost::adaptors::transformed;
    auto tostr = static_cast<std::string(*)(int)>(std::to_string);

    auto array = {1,2,3,4};
    std::cout << join(array | transformed(tostr), ",") << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

感谢执政官.

您可以处理任何值类型,如下所示:

template<class Container>
std::string join(Container const & container, std::string delimiter) {
  using boost::algorithm::join;
  using boost::adaptors::transformed;
  using value_type = typename Container::value_type;

  auto tostr = static_cast<std::string(*)(value_type)>(std::to_string);
  return join(container | transformed(tostr), delimiter);
};
Run Code Online (Sandbox Code Playgroud)


sbi*_*sbi 11

这只是试图解决1800 INFORMATION对他缺乏通用性的第二个解决方案的评论所给出的谜语,而不是试图回答这个问题:

template <class Str, class It>
Str join(It begin, const It end, const Str &sep)
{
  typedef typename Str::value_type     char_type;
  typedef typename Str::traits_type    traits_type;
  typedef typename Str::allocator_type allocator_type;
  typedef std::basic_ostringstream<char_type,traits_type,allocator_type>
                                       ostringstream_type;
  ostringstream_type result;

  if(begin!=end)
    result << *begin++;
  while(begin!=end) {
    result << sep;
    result << *begin++;
  }
  return result.str();
}
Run Code Online (Sandbox Code Playgroud)

Works On My Machine(TM).


Joe*_*der 7

很多模板/想法.我的不是通用的或有效的,但我只是遇到了同样的问题,并希望把它作为简短而甜蜜的东西.它赢得最短的线数... :)

std::stringstream joinedValues;
for (auto value: array)
{
    joinedValues << value << ",";
}
//Strip off the trailing comma
std::string result = joinedValues.str().substr(0,joinedValues.str().size()-1);
Run Code Online (Sandbox Code Playgroud)


小智 5

string s;
for (auto i : v)
    s += (s.empty() ? "" : ",") + to_string(i);
Run Code Online (Sandbox Code Playgroud)

  • 欢迎使用堆栈溢出!虽然这段代码可以解决问题,但最好为可能不理解这段代码的人添加详细说明并解释它是如何工作的。 (8认同)