我正在尝试以最佳方式遍历静态字符串数组的所有元素。 我希望能够在一行上声明它,并轻松地从中添加/删除元素,而不必跟踪数字。 听起来真的很简单,不是吗?
可能的非解决方案:
1 2 3 4 5 6
| vector<string> v;
v.push_back("abc");
b.push_back("xyz");
for(int i = 0; i < v.size(); i++)
cout << v[i] << endl; |
问题-无法在带有字符串列表的一行上创建矢量
可能的非解决方案2:
1
| string list[] = {"abc","xyz"}; |
问题-无法自动获取字符串数量(据我所知)。
必须有一个简单的方法来执行此操作。
C ++ 11添加了初始化列表以允许以下语法:
1
| std::vector<std::string> v = {"Hello","World"}; |
至少在GCC 4.4中和仅在Visual Studio 2013中添加了对此C ++ 11功能的支持。
您可以从静态创建的char*数组中简洁地初始化vector:
1 2
| 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");这样的单行就可以工作。
Problems - no way to get the number of strings automatically (that i know of).
有一种沼泽标准的方式来执行此操作,许多人(包括MS)为诸如以下内容定义了arraysize宏:
1
| #define arraysize(ar) (sizeof(ar) / sizeof(ar[0])) |
像这样在C ++中声明一个字符串数组:char array_of_strings[][]
例如:char array_of_strings[200][8192];
将容纳200个字符串,每个字符串的大小为8kb或8192字节。
使用strcpy(line[i],tempBuffer);将数据放入字符串数组中。
一种可能性是使用NULL指针作为标志值:
1 2 3 4 5
| const char *list[] = {"dog","cat", NULL};
for (char **iList = list; *iList != NULL; ++iList)
{
cout << *iList;
} |
您可以使用Boost范围库中的begin和end函数轻松找到基本数组的末端,并且与宏解决方案不同,如果不小心将其应用于数组,这将产生编译错误而不是破坏行为。指针。
1 2
| 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.
它不起作用的情况是"数组"实际上只是一个指针,而不是一个实际的数组。同样,由于数组传递给函数的方式(转换为指向第一个元素的指针),即使签名看起来像数组some_function(string parameter[])确实是some_function(string *parameter),它也不能跨函数调用工作。
这是一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #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] <<"\
";
const std::vector<string> v(list, list + len);
std::copy(v.begin(), v.end(), std::ostream_iterator<string>(std::cout,"\
"));
} |
1 2 3 4 5 6 7
| #include <boost/foreach.hpp>
const char* list[] = {"abc","xyz"};
BOOST_FOREACH(const char* str, list)
{
cout << str << endl;
} |
除了这个宏,我可以建议这个:
1 2 3 4 5 6 7
| 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)但是,我们不希望使用宏,因为该宏可能会意外地用于指针。该函数只能在编译时数组上使用。
因此,我们使用函数的定义性来使宏"安全"。如果函数存在(即大小为非零),则我们使用上面的宏。如果该函数不存在,则返回错误值。
您可以直接声明一个字符串数组,例如string s[100];。
然后,如果要访问特定元素,则可以像s[2][90]这样直接获得它。出于迭代目的,请使用
s[i].size()功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #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,"\
" ) );
} |