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

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.

1

12 Answers

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.

1

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.

1

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])) 
2

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.

2

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; } 
2

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)); 

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).

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

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.

#include <boost/foreach.hpp> const char* list[] = {"abc", "xyz"}; BOOST_FOREACH(const char* str, list) { cout << str << endl; } 
#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" ) ); } 

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.

You Might Also Like