char数组的C++向量

Posted

技术标签:

【中文标题】char数组的C++向量【英文标题】:C++ vector of char array 【发布时间】:2011-01-24 10:32:59 【问题描述】:

我正在尝试编写一个包含 char 数组向量的程序,但遇到了一些问题。

char test [] =  'a', 'b', 'c', 'd', 'e' ;

vector<char[]> v;

v.push_back(test);

抱歉,这必须是一个字符数组,因为我需要能够生成字符列表,因为我试图获得类似的输出。

一个 一个 一个 广告 一个 一个 bc

谁能指出我正确的方向?

谢谢

【问题讨论】:

忘记向量,只使用 std::string。然后你可以使用 += 来添加更多的字符。 我不需要只添加我需要将之前的字符更改为数组中的下一个字符的字符。 【参考方案1】:

你需要

char test[] = "abcde";  // This will add a terminating \0 character to the array
std::vector<std::string> v;
v.push_back(test);

如果你打算制作一个字符向量而不是字符串向量,

std::vector<char> v(test, test + sizeof(test)/sizeof(*test));

表达式sizeof(test)/sizeof(*test)用于计算数组test中的元素个数。

【讨论】:

使用这个我将如何 push_back 另一个测试实例将其添加到现有向量中? 关于sizeof(test)/sizeof(*test),STL库提供std::size,所以可以用size(test)代替。它不仅更短,而且更正确。【参考方案2】:

您不能将数组存储在向量中(或任何其他标准库容器中)。标准库容器存储的东西必须是可复制和可赋值的,而数组不是这两种。

如果您确实需要将数组放入向量中(并且您可能不需要 - 使用向量的向量或字符串的向量更可能是您需要的),那么您可以将数组包装在一个结构中:

struct S 
  char a[10];
;

然后创建一个结构向量:

vector <S> v;
S s;
s.a[0] = 'x';
v.push_back( s );

【讨论】:

数组如何不可复制或不可分配? C 风格的数组(与 std::array 相对)在编译或运行时没有可用的信息来让人们知道数组的大小,或包含在一个数组元素。如果没有该大小信息,编译器就无法将一个数组复制或分配给另一个数组。 memcpy(array2,array1,some_size) 在答案中使用的动词的意义上不是“复制”。【参考方案3】:

使用std::string 代替字符数组

std::string k ="abcde";
std::vector<std::string> v;
v.push_back(k);

【讨论】:

虽然这可能非常适合这个实现,但据我了解,std::string 实现并不能保证有连续的内存存储。如果有人要使用它来接收流并使用此解决方案,它可能是 一个问题。此外,如果您在流中有 'NULL' 字符,您将遇到 std::string 问题。 @modalgeek C++98 不保证连续存储。然而,所有已知的实现都提供了它,并且他们添加了它是一个非常有用的保证。您可以放心地假设向量和字符串都是连续的。【参考方案4】:

您可以使用boost::array 来做到这一点:

boost::array<char, 5> test = 'a', 'b', 'c', 'd', 'e';
std::vector<boost::array<char, 5> > v;
v.push_back(test);

编辑:

或者您可以使用如下所示的向量向量:

char test[] = 'a', 'b', 'c', 'd', 'e';
std::vector<std::vector<char> > v;
v.push_back(std::vector<char>(test, test + sizeof(test)/ sizeof(test[0])));

【讨论】:

【参考方案5】:

您可以直接定义一个char类型的向量,如下所示。

vector<char> c = 'a', 'b', 'c';
vector < vector<char> > t = 'a','a', 'b','b';

【讨论】:

【参考方案6】:

我发现将 char* 放入 std::vector 是可以的:

//  1 - A std::vector of char*, more preper way is to use a std::vector<std::vector<char>> or std::vector<std::string>
std::vector<char*> v(10, "hi!");    //  You cannot put standard library containers e.g. char[] into std::vector!
for (auto& i : v)

    //std::cout << i << std::endl;
    i = "New";

for (auto i : v)

    std::cout << i << std::endl;

【讨论】:

【参考方案7】:

FFWD 到 2019 年。尽管此代码在 2011 年也有效。

// g++ prog.cc -Wall -std=c++11
#include <iostream>
#include <vector>

 using namespace std;

 template<size_t N>
    inline 
      constexpr /* compile time */
      array<char,N> string_literal_to_array ( char const (&charrar)[N] )
 
    return std::to_array( charrar) ;
 

 template<size_t N>
    inline 
      /* run time */
      vector<char> string_literal_to_vector ( char const (&charrar)[N] )
 
    return  charrar, charrar + N ;
 


int main()

   constexpr auto arr = string_literal_to_array("Compile Time");
   auto cv = string_literal_to_vector ("Run Time") ;
   return 42;

建议:尝试优化std::string 的使用。对于字符缓冲std::array&lt;char,N&gt; 是最快的,std::vector&lt;char&gt; 更快。

https://wandbox.org/permlink/wcasstoY56MWbHqd

【讨论】:

【参考方案8】:

事实上,从技术上讲,您可以不直接将 C++ 数组存储在向量中,而是使用简单的解决方法。这很有意义。 anon已经回答了问题,但仍需要一些解释。将数组包装在一个类中将使向量数据满足多维数组的要求。 C++ 11 及更高版本中的 STL 已经提供了这样的包装器 std::array向量的向量适合多种用途,但不是答案,在某些情况下它是错误的。由于没有清楚地了解数组指针之间或多维数组数组数组。向量的向量包含作为元素的向量:每个向量都包含大小、容量、指向内存中随机数据段的数据的指针。这些段不会像在多维数组中那样一个接一个地放置。这将导致与不支持 C++ 矢量 的其他编程语言或库的互操作性出现问题。 但是数组向量将始终指向一个连续的内存段,在一个地方以正确的顺序包含多维数组的所有段。从技术上讲,数据指针将指向与多维数组相同的东西。没有充分的理由保持每个数组元素的大小,而已知它对于所有元素都是相同的。至少它是多余的,但这不是一个大问题。更大的问题是,它破坏了多维数组的结构。这是与其他不支持C++ 向量 的编程语言或库的互操作性问题。 因此,可以通过将数组包装在一个类中或使用现有的std::array 来间接地创建数组向量。它将数据存储在内存中,与二维数组相同。这种方法已经被许多图书馆广泛使用。在低级别,它将很容易与不支持 C++ 矢量的 API 互操作。因此,如果不使用 std::array,它将如下所示:

int main()

    struct ss
    
        int a[5];
        int& operator[] (const int& i)  return a[i]; 
     a 1,2,3,4,5 , b 9,8,7,6,5 ;

    vector<ss> v;
    v.resize(10);
    v[0] = a;
    v[1] = b;
    //all the rest is uninitialised array
    v.push_back(a); // pushes to the end, with reallocation
    v.push_back(b); // pushes to the new end, with reallocation

    auto d = v.data();
    // cin >> v[1][3]; //input any element from stdin
    cout << "show two element: "<< v[1][2] <<":"<< v[1][3] << endl;
    return 0;

在内存中它看起来非常可预测,十二个数组,两个在开头,两个在结尾初始化,另外八个在中间未初始化,用零填充

C++11及以上有std::array,无需重新发明:

....
#include<array>
....
int main()

    vector<array<int, 5>> v;
    v.reserve(10); //set capacity
    v.resize(2);
    v[0] = array<int, 5> 1, 2, 3, 4, 5;
    v[1] = array<int, 5> 9, 8, 7, 6, 5;

    //note, since size does not exceed capacity
    //this push_back will cause no reallocation and no relocation:
    v.push_back(array<int, 5> 7, 2, 53, 4, 5 );
    ///cin >> v[1][1];
    auto d = v.data();

现在,这就是为什么向量的向量不是答案的原因。假设以下代码

int main()

    vector<vector<int>> vv =   1,2,3,4,5 ,  9,8,7,6,5  ;
    auto dd = vv.data();
    return 0;

数据在内存中的存储方式永远猜不透,绝对不是多维数组

【讨论】:

以上是关于char数组的C++向量的主要内容,如果未能解决你的问题,请参考以下文章

用单个 char* 填充向量,指向 C 中 char* 数组的基数

C++ 通过引用传递向量字符指针

std::vector<std::string> 到 char* 数组

将 C# 数组传递给 C++ 向量

将 numpy 数组公开为 C++ 向量

我如何按类属性对C++向量数组进行排序[重复]