How to declare an array of strings in C++?

90

I am trying to iterate over all the elements of a static array of strings in the best possible way. I want to be able to declare it on one line and easily add/remove elements from it without having to keep track of the number. Sounds really simple, doesn't it?

Possible non-solutions:

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

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

Problems - no way to create the vector on one line with a list of strings

Possible non-solution 2:

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

Problems - no way to get the number of strings automatically (that I know of).

There must be an easy way of doing this.

This question is tagged with c++ arrays

~ Asked on 2008-08-29 18:41:35

12 Answers


108

C++ 11 added initialization lists to allow the following syntax:

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

Support for this C++ 11 feature was added in at least GCC 4.4 and only in Visual Studio 2013.

~ Answered on 2008-08-29 22:39:43


37

You can concisely initialize a vector<string> from a statically-created char* array:

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

This copies all the strings, by the way, so you use twice the memory. You can use Will Dean's suggestion to replace the magic number 3 here with arraysize(str_array) -- although I remember there being some special case in which that particular version of arraysize might do Something Bad (sorry I can't remember the details immediately). But it very often works correctly.

Also, if you're really gung-ho about the one line thingy, you can define a variadic macro so that a single line such as DEFINE_STR_VEC(strvector, "hi", "there", "everyone"); works.

~ Answered on 2008-08-29 21:21:08


22

Problems - no way to get the number of strings automatically (that i know of).

There is a bog-standard way of doing this, which lots of people (including MS) define macros like arraysize for:

#define arraysize(ar)  (sizeof(ar) / sizeof(ar[0]))

~ Answered on 2008-08-29 18:48:07


8

Declare an array of strings in C++ like this : char array_of_strings[][]

For example : char array_of_strings[200][8192];

will hold 200 strings, each string having the size 8kb or 8192 bytes.

use strcpy(line[i],tempBuffer); to put data in the array of strings.

~ Answered on 2012-01-11 14:09:20


7

One possiblity is to use a NULL pointer as a flag value:

const char *list[] = {"dog", "cat", NULL};
for (char **iList = list; *iList != NULL; ++iList)
{
    cout << *iList;
}

~ Answered on 2008-09-15 19:48:19


4

You can use the begin and end functions from the Boost range library to easily find the ends of a primitive array, and unlike the macro solution, this will give a compile error instead of broken behaviour if you accidentally apply it to a pointer.

const char* array[] = { "cat", "dog", "horse" };
vector<string> vec(begin(array), end(array));

~ Answered on 2008-09-23 23:05:10


3

You can use Will Dean's suggestion [#define arraysize(ar) (sizeof(ar) / sizeof(ar[0]))] to replace the magic number 3 here with arraysize(str_array) -- although I remember there being some special case in which that particular version of arraysize might do Something Bad (sorry I can't remember the details immediately). But it very often works correctly.

The case where it doesn't work is when the "array" is really just a pointer, not an actual array. Also, because of the way arrays are passed to functions (converted to a pointer to the first element), it doesn't work across function calls even if the signature looks like an array — some_function(string parameter[]) is really some_function(string *parameter).

~ Answered on 2008-08-29 21:34:43


3

Here's an example:

#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"));
}

~ Answered on 2008-08-29 20:01:31


2

Instead of that macro, might I suggest this one:

template<typename T, int N>
inline size_t array_size(T(&)[N])
{
    return N;
}

#define ARRAY_SIZE(X)   (sizeof(array_size(X)) ? (sizeof(X) / sizeof((X)[0])) : -1)

1) We want to use a macro to make it a compile-time constant; the function call's result is not a compile-time constant.

2) However, we don't want to use a macro because the macro could be accidentally used on a pointer. The function can only be used on compile-time arrays.

So, we use the defined-ness of the function to make the macro "safe"; if the function exists (i.e. it has non-zero size) then we use the macro as above. If the function does not exist we return a bad value.

~ Answered on 2008-09-01 01:05:36


2

#include <boost/foreach.hpp>

const char* list[] = {"abc", "xyz"};
BOOST_FOREACH(const char* str, list)
{
    cout << str << endl;
}

~ Answered on 2008-09-06 05:34:36


1

You can directly declare an array of strings like string s[100];. Then if you want to access specific elements, you can get it directly like s[2][90]. For iteration purposes, take the size of string using the s[i].size() function.

~ Answered on 2016-01-28 17:03:04


1

#include <iostream>
#include <string>
#include <vector>
#include <boost/assign/list_of.hpp>

int main()
{
    const std::vector< std::string > v = boost::assign::list_of( "abc" )( "xyz" );
    std::copy(
        v.begin(),
        v.end(),
        std::ostream_iterator< std::string >( std::cout, "\n" ) );
}

~ Answered on 2009-12-12 13:33:11


Most Viewed Questions: