【问题标题】:How to convert STL string vector into char* in an elegant/quick way?如何以优雅/快速的方式将 STL 字符串向量转换为 char*?
【发布时间】:2011-08-10 21:55:56
【问题描述】:

这分为更小的阶段:

  1. 如何计算向量中所有字符串的总长度?
  2. 分配 char* 内存空间
  3. 将向量字符串复制到该空间中

有没有一种快速优雅的方法来做到这一点?

【问题讨论】:

  • “字符串向量”是什么意思?这是std::vector<std::string> 还是std::vector<char>
  • 我假设是前者,因为向量中有多个字符串。可能是 vector 虽然看起来不太可能。
  • 或者输出应该是 char**。很难理解你的意思。
  • 目标中的字符串之间是否需要任何分隔符,如果需要,使用哪个分隔符?
  • 为什么要执行这个操作?

标签: c++ string stl vector


【解决方案1】:

我能想到的最优雅但可能不是最快的方式如下:

std::string s = std::accumulate(v.begin(), v.end(), std::string());
char * c = new char[s.size() + 1];
std::strcpy(c,s.c_str());

虽然我自己不是裸动态分配的拥趸,个人也不会使用它,但还是留给大家解决吧。

如果您需要在元素之间添加空格分隔符,它会变得有点复杂,我可能会使用不同的解决方案,如下所示:

std::ostringstream oss;
std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(oss," "));
size_t sz = oss.str().size();
if(sz) --sz; // truncate trailing space if there is one
char * c = new char[sz+1];
std::copy_n(oss.str().c_str(), sz, c);
c[sz] = 0;

【讨论】:

  • 我会做类似 ildjarn 所做的事情,但我不想投入那么多精力。
  • 除了在向量元素之间添加空格外,我该如何做同样的事情?我想我们需要修改 std::accumulate 中的运算符
【解决方案2】:

这是一个 C++0x 实现:

#include <cstddef>
#include <algorithm>
#include <numeric>
#include <string>
#include <vector>

std::vector<char> concat_strings(std::vector<std::string> const& vecs)
{
    std::size_t const cumulative_length = std::accumulate(
        vecs.begin(),
        vecs.end(),
        static_cast<std::size_t>(0),
        [](std::size_t const acc, std::string const& str)
        {
            return acc + str.size();
        }
    );

    std::vector<char> ret;
    ret.reserve(cumulative_length);

    std::for_each(
        vecs.begin(),
        vecs.end(),
        [&ret](std::string const& str)
        {
            ret.insert(ret.end(), str.begin(), str.end());
        }
    );

    return ret;
}

生成的std::vector&lt;char&gt; 是您的有效char*

对于 C++03,情况大致相同,但您需要适当的仿函数来代替 lambda(或使用 C++03 lambda 库,例如 Boost.Phoenix)。

【讨论】:

    【解决方案3】:

    这不是一个优雅的要求,所以我想不出优雅的解决方案。

    未经测试的代码

    vector<string> vec = ...;
    size_t total_size = 0;
    for (size_t i = 0; i < vec.size(); ++i)
      total_size += vec[i].size();
    char* mem = new char[total_size];
    char* p = mem;
    for (size_t i = 0; i < vec.size(); ++i)
    {
      memcpy(p, vec[i].data(), vec[i].size());
      p += vec[i].size();
    }
    

    【讨论】:

    • 将分配大小更改为total_size+1并添加mem[total_size] = '\0';
    • 我不确定 OP 是否需要一个以空字符结尾的字符串。例如,他可能正在通过 TCP 套接字发送数据。
    • 好点。但如果他需要它是 C 风格的字符串,他显然需要 '\0'
    【解决方案4】:

    这里是STL方式:

    #include <algorithm>  // std::copy
    #include <iostream>   // std::cout
    #include <iterator>   // std::ostream_iterator
    #include <sstream>    // std::ostring_stream
    #include <string>     // std::string
    #include <vector>     // std::Vector
    
    using namespace std;
    
    typedef std::vector<std::string> string_vector;
    
    int main( int argc, char ** argv )
    {
      string_vector v;
      v.push_back("string 1, ");
      v.push_back("string 2, ");
      v.push_back("string 3");
    
      std::ostringstream os;
      std::copy( v.begin(), v.end(), std::ostream_iterator<std::string>( os, "" ) );
      std::string result = os.str();
    
      std::cout << "result: " << result << std::endl;
    
      return 0;
    }
    

    输出:

    result: string 1, string 2, string 3
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-19
      • 1970-01-01
      • 2011-08-07
      • 1970-01-01
      • 2015-06-19
      • 2021-12-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多