Как хранить строки фиксированной длины внутри std :: vector - PullRequest
3 голосов
/ 18 августа 2011

Я хочу имитировать структуру:

char [][40] = { "Stack", "Overflow", "Exchange", "Network" };

, используя std::vector, чтобы я мог заполнять ее во время выполнения и динамически изменять размер vector, но сохраняя элементы-члены, расположенные внутриблоки фиксированного размера.

Статическая инициализация - не мой вопрос - я могу сделать это, используя boost::assign или другие приемы.

Ответы [ 4 ]

2 голосов
/ 18 августа 2011

Я бы использовал что-то вроде Boost.Array :

typedef boost::array<char, 40> arr_t;
std::vector<arr_t> vec;
{
    arr_t arr = { "Stack" };
    vec.push_back(arr);
}
{
    arr_t arr = { "Overflow" };
    vec.push_back(arr);
}
{
    arr_t arr = { "Exchange" };
    vec.push_back(arr);
}
{
    arr_t arr = { "Network" };
    vec.push_back(arr);
}

Если вы используете достаточно свежий компилятор, вместо Boost вы, вероятно, можете использовать std::array<> (C++ 11; #include <array>) или std::tr1::array<> (C ++ 03 с TR1; #include <array> или #include <tr1/array>, в зависимости от платформы).

1 голос
/ 18 августа 2011
struct fixed_string { 
    char data[40];

    fixed_string(char const *init);
};

std::vector<fixed_string> whatever;

Если у вас есть C ++ 11 (или хотя бы TR1), вы, вероятно, захотите использовать std::array вместо fixed_string. Я думаю, что Boost также имеет эквивалент.

В случае, если кому-то интересно, почему я поместил его в struct вместо непосредственного создания вектора массива: потому что элементы в vector должны быть копируемыми и назначаемыми, а пустой массив - ни то, ни другое.

0 голосов
/ 18 августа 2011

Ответ Парапуры правильный, но вы будете хранить указатели на строки.Если исходный массив символов выпадает из области видимости, вы потеряете размещенную информацию.Если этот вектор используется в другом месте, он должен выделить (и освободить!) Свою собственную память.Это может быть сделано при вводе.

Вот пример программы, которая делает это.

#include <vector>
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
using std::vector;

int main()
{
    int numEntries = 4;
    const int strlen = 40;

    // Parapura's correct answer, but let's expand this further
    vector<char*> strvec;
    char* input = 0;
    int i;

    cout << "Enter four names." << endl;
    for (i=0; i<numEntries; i++)
    {
        // Allocate some memory to store in the vector
        input = new char[strlen];
        cout << "Name: ";
        cin.get(input, strlen);
        cin.ignore(strlen, '\n');

        // Push the populated memory into the vector.
        // Now we can let 'input' fall out of scope.
        strvec.push_back(input);
    }
    cout << endl;

    /* -- cool code here! -- */

    cout << "List of names." << endl;
    for (i=0; i<numEntries; i++)
    {
        cout << strvec[i] << endl;
    }

    /* -- more cool code! -- */

    // don't forget to clean up!
    for (i=0; i<numEntries; i++)
    {
        delete[] strvec[i];
    }

    return 0;
}
0 голосов
/ 18 августа 2011

Может быть vector в vector помогает.Здесь размер фиксирован, строки можно использовать в чистом C.

vector< vector<char> > vector_of_strings;

// Add new string
vector_of_strings.push_back( vector<char>(40) );
// use the string
strcpy( &vector_of_strings[0][0], "text" );
...