如何在C ++中声明字符串数组?
我正在尝试以最佳方式遍历静态字符串数组的所有元素。我希望能够在一行上声明它,并轻松地从中添加/删除元素,而不必跟踪数字。听起来真的很简单,不是吗?
可能的非解决方案:
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"};
问题是没有办法自动获取字符串数量(我知道)。
必须有一个简单的方法来执行此操作。
解决方案
回答
提升分配库似乎正是我们要寻找的。它使向容器分配常量比以往更加容易。
回答
Problems - no way to get the number of strings automatically (that i know of).
有一个沼泽标准的方式来做到这一点,很多人(包括MS)为诸如" arraysize"之类的宏定义:
#define arraysize(ar) (sizeof(ar) / sizeof(ar[0]))
回答
这是一个例子:
#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")); }
回答
我们可以从静态创建的char *
数组中简洁地初始化一个vector <string>
:
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");之类的单行有效。
回答
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)
。
回答
C ++ 11添加了初始化列表以允许以下语法:
std::vector<std::string> v = {"Hello", "World"};
至少在GCC 4.4中添加了对此C ++ 11功能的支持,并且仅在Visual Studio 2013中添加了对此功能的支持。
回答
除了这个宏,我可以建议以下一个宏:
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)但是,我们不希望使用宏,因为该宏可能会意外地用于指针。该函数只能在编译时数组上使用。
因此,我们使用函数的定义性来使宏"安全"。如果函数存在(即大小为非零),则我们使用上面的宏。如果该函数不存在,则返回错误值。
回答
#include <boost/foreach.hpp> const char* list[] = {"abc", "xyz"}; BOOST_FOREACH(const char* str, list) { cout << str << endl; }
回答
一种可能性是使用NULL指针作为标志值:
const char *list[] = {"dog", "cat", NULL}; for (char **iList = list; *iList != NULL; ++iList) { cout << *iList; }
回答
试图提高Craig H的答案,即我们应该使用boost :: assign,但我没有代表:(
我在Andrei Alexandrescu在《 C / C ++用户杂志》,第16卷,第9期,1998年9月,第73-74页上读过的第一篇文章中遇到了类似的技术(全文引用是因为它是在我的实现的评论中)。从那以后我一直在使用他的代码)。
模板是朋友。
回答
我们可以使用Boost范围库中的begin
和end
函数轻松地找到基本数组的结尾,并且与宏解决方案不同,如果我们不小心将其应用于数组,这将产生编译错误而不是破坏行为。指针。
const char* array[] = { "cat", "dog", "horse" }; vector<string> vec(begin(array), end(array));
回答
#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" ) ); }