繁体   English   中英

C++ 字符数组向量

[英]C++ vector of char array

我正在尝试编写一个具有字符数组向量的程序,但遇到了一些问题。

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

vector<char[]> v;

v.push_back(test);

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

aaabacadaebabc

任何人都可以指出我正确的方向吗?

谢谢

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

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

struct S {
  char a[10];
};

然后创建一个结构向量:

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

你需要

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 中元素的数量。

使用std::string而不是 char-arrays

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

您可以使用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])));

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

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

实际上,从技术上讲,您可以不直接将 C++ 数组存储在向量中,而是使用简单的解决方法。 这很有意义。 问题已由 anon 回答,但仍需要一些解释。 将数组包装在一个类中将使向量数据满足多维数组的要求。 C++ 11 和 upper 中的 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 和 upper 有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;
}

永远猜不到数据在内存中是如何存储的,绝对不是多维数组

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<char,N>是最快的, std::vector<char>更快。

https://wandbox.org/permlink/wcasstoY56MWbHqd

我发现可以将 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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM