91

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.

4

12 回答 12

108

C++ 11 添加了初始化列表以允许以下语法:

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

至少在GCC 4.4中添加了对此 C++ 11 功能的支持,并且仅在Visual Studio 2013中添加。

于 2008-08-29T22:39:43.120 回答
37

vector<string>您可以从静态创建的char*数组简洁地初始化 a :

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

顺便说一句,这会复制所有字符串,因此您使用了两倍的内存。您可以使用 Will Dean 的建议将此处的幻数 3 替换为 arraysize(str_array) ——尽管我记得在某些特殊情况下,特定版本的 arraysize 可能会做坏事(抱歉,我不记得细节了) . 但它通常可以正常工作。

此外,如果你真的对单行很感兴趣,你可以定义一个可变参数宏,这样单行就可以DEFINE_STR_VEC(strvector, "hi", "there", "everyone");工作了。

于 2008-08-29T21:21:08.677 回答
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]))
于 2008-08-29T18:48:07.187 回答
8

在 C++ 中声明一个字符串数组,如下所示:char array_of_strings[][]

例如 :char array_of_strings[200][8192];

将包含 200 个字符串,每个字符串的大小为 8kb 或 8192 字节。

用于strcpy(line[i],tempBuffer); 将数据放入字符串数组中。

于 2012-01-11T14:09:20.660 回答
7

一种可能性是使用 NULL 指针作为标志值:

const char *list[] = {"dog", "cat", NULL};
for (char **iList = list; *iList != NULL; ++iList)
{
    cout << *iList;
}
于 2008-09-15T19:48:19.190 回答
4

您可以使用 Boost 范围库中的beginend函数轻松找到原始数组的结尾,并且与宏解决方案不同,如果您不小心将其应用于指针,这将给出编译错误而不是破坏行为。

const char* array[] = { "cat", "dog", "horse" };
vector<string> vec(begin(array), end(array));
于 2008-09-23T23:05:10.107 回答
3

这是一个例子:

#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"));
}
于 2008-08-29T20:01:31.097 回答
3

您可以使用 Will Dean 的建议 [ #define arraysize(ar) (sizeof(ar) / sizeof(ar[0]))] 将此处的幻数 3 替换为 arraysize(str_array) - 尽管我记得有一些特殊情况,其中特定版本的 arraysize 可能会做一些坏事(抱歉,我不记得细节了立即地)。但它通常可以正常工作。

它不起作用的情况是“数组”实际上只是一个指针,而不是实际的数组。此外,由于数组传递给函数的方式(转换为指向第一个元素的指针),即使签名看起来像一个数组,它也不能跨函数调用工作——some_function(string parameter[])实际上是some_function(string *parameter).

于 2008-08-29T21:34:43.197 回答
2

我可以建议这个宏,而不是那个宏:

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)我们想使用宏来使其成为编译时常量;函数调用的结果不是编译时常量。

2) 但是,我们不想使用宏,因为宏可能会意外地用在指针上。该函数只能用于编译时数组。

因此,我们使用函数的定义性来使宏“安全”;如果函数存在(即它的大小不为零),那么我们使用上面的宏。如果该函数不存在,我们将返回一个错误值。

于 2008-09-01T01:05:36.043 回答
2
#include <boost/foreach.hpp>

const char* list[] = {"abc", "xyz"};
BOOST_FOREACH(const char* str, list)
{
    cout << str << endl;
}
于 2008-09-06T05:34:36.587 回答
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" ) );
}
于 2009-12-12T13:33:11.133 回答
1

您可以直接声明一个字符串数组,例如string s[100];. 然后如果你想访问特定的元素,你可以直接像s[2][90]. 出于迭代目的,使用该 s[i].size()函数获取字符串的大小。

于 2016-01-28T17:03:04.320 回答