Как объявить массив строк в C ++? - PullRequest
84 голосов
/ 29 августа 2008

Я пытаюсь перебрать все элементы статического массива строк в лучшем виде. Я хочу иметь возможность объявить его в одной строке и легко добавлять / удалять элементы без необходимости отслеживать количество. Звучит очень просто, не правда ли?

Возможные не решения:

vector<string> v;
v.push_back("abc");
b.push_back("xyz");

for(int i = 0; i < v.size(); i++)
    cout << v[i] << endl;

Проблемы - нет способа создать вектор на одной строке со списком строк

Возможное отсутствие решения 2:

string list[] = {"abc", "xyz"};

Проблемы - нет способа автоматически получить количество строк (о которых я знаю).

Должен быть простой способ сделать это.

Ответы [ 15 ]

104 голосов
/ 30 августа 2008

C ++ 11 добавил списки инициализации, чтобы разрешить следующий синтаксис:

std::vector<std::string> v = {"Hello", "World"};

Поддержка этой функции C ++ 11 была добавлена ​​как минимум в GCC 4.4 и только в Visual Studio 2013 .

36 голосов
/ 30 августа 2008

Вы можете кратко инициализировать vector<string> из статически созданного массива char*:

char* strarray[] = {"hey", "sup", "dogg"};
vector<string> strvector(strarray, strarray + 3);

Кстати, это копирует все строки, поэтому вы используете вдвое больше памяти. Вы можете использовать предложение Уилла Дина, чтобы заменить магическое число 3 здесь на arraysize (str_array) - хотя я помню, что был какой-то особый случай, когда эта конкретная версия массива могла бы сделать что-то плохое (извините, я не могу сразу вспомнить детали) , Но это очень часто работает правильно.

Кроме того, если вы действительно любите одну строку, вы можете определить макрос с переменным значением, чтобы работала одна строка, такая как DEFINE_STR_VEC(strvector, "hi", "there", "everyone");.

26 голосов
/ 29 августа 2008

Библиотека для буст-назначения , кажется, именно то, что вы ищете. Это делает присвоение констант контейнерам проще, чем когда-либо.

23 голосов
/ 29 августа 2008

Проблемы - нет способа автоматически получить количество строк (о которых я знаю).

Существует стандартный способ сделать это, когда многие люди (включая MS) определяют макросы, например arraysize для:

#define arraysize(ar)  (sizeof(ar) / sizeof(ar[0]))
9 голосов
/ 11 января 2012

Объявите массив строк в C ++ следующим образом: char array_of_strings[][]

Например: char array_of_strings[200][8192];

будет содержать 200 строк, каждая строка имеет размер 8 КБ или 8192 байта.

используйте strcpy(line[i],tempBuffer); для помещения данных в массив строк.

7 голосов
/ 15 сентября 2008

Одной из возможностей является использование указателя NULL в качестве значения флага:

const char *list[] = {"dog", "cat", NULL};
for (char **iList = list; *iList != NULL; ++iList)
{
    cout << *iList;
}
4 голосов
/ 24 сентября 2008

Вы можете использовать функции begin и end из библиотеки Boost range, чтобы легко находить концы примитивного массива, и в отличие от макрокоманды, это даст ошибку компиляции вместо неработающего поведения, если вы случайно примените это к указателю.

const char* array[] = { "cat", "dog", "horse" };
vector<string> vec(begin(array), end(array));
3 голосов
/ 16 сентября 2008

Пытался поднять ответ Крэйга Х, что вы должны использовать boost :: assign, но у меня нет повторения: (

Я столкнулся с подобной техникой в ​​первой статье, которую я когда-либо читал Андреем Александреску в Журнале пользователей C / C ++ , том 16, № 9, сентябрь 1998 г., стр. 73-74 потому что это в комментариях к моей реализации его кода, который я использовал с тех пор).

Шаблоны - ваш друг.

3 голосов
/ 30 августа 2008

Вы можете использовать предложение Уилла Дина [#define arraysize(ar) (sizeof(ar) / sizeof(ar[0]))], чтобы заменить магическое число 3 здесь на arraysize (str_array) - хотя я помню, что был какой-то особый случай, когда эта конкретная версия arraysize могла сделать что-то плохое не могу вспомнить детали сразу). Но это очень часто работает правильно.

Случай, когда он не работает, это когда массив в действительности является просто указателем, а не фактическим массивом. Кроме того, из-за способа, которым массивы передаются в функции (преобразованные в указатель на первый элемент), он не работает при вызове функций, даже если подпись выглядит как массив & mdash; some_function(string parameter[]) действительно some_function(string *parameter).

3 голосов
/ 30 августа 2008

Вот пример:

#include <iostream>
#include <string>
#include <vector>
#include <iterator>

int main() {
    const char* const list[] = {"zip", "zam", "bam"};
    const size_t len = sizeof(list) / sizeof(list[0]);

    for (size_t i = 0; i < len; ++i)
        std::cout << list[i] << "\n";

    const std::vector<string> v(list, list + len);
    std::copy(v.begin(), v.end(), std::ostream_iterator<string>(std::cout, "\n"));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...