【问题标题】:How to declare an array of strings in C++?如何在 C++ 中声明一个字符串数组?
【发布时间】:2010-09-07 07:00:42
【问题描述】:

我正在尝试以最佳方式迭代字符串静态数组的所有元素。我希望能够在一行上声明它并轻松地从中添加/删除元素,而无需跟踪数字。听起来很简单,不是吗?

可能的非解决方案:

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

问题 - 无法自动获取字符串的数量(据我所知)。

必须有一种简单的方法来做到这一点。

【问题讨论】:

  • boost assign library 似乎正是您想要的。它使为容器分配常量比以往任何时候都容易。

标签: c++ arrays


【解决方案1】:

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

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

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

【讨论】:

  • 2018.刚开始 C++ 并做了一些关于灵活数组的研究。最终只使用向量......
【解决方案2】:

您可以从静态创建的 char* 数组简洁地初始化 vector&lt;string&gt;

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"); 这样的单行就可以工作了。

【讨论】:

  • 既然strarray在header中,会不会违反单定义规则?
【解决方案3】:

问题 - 无法自动获取字符串的数量(据我所知)。

有一种标准的方法可以做到这一点,很多人(包括 MS)定义像 arraysize 这样的宏:

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

【讨论】:

  • 或者,可以使用类似这样的东西:template&lt;typename T, size_t N&gt; inline size_t arraysize(T (&amp;ar)[N]) { return N; }(内联关键字不是必需的,但用于记录函数的意图。我相信,现代编译器理论上应该能够返回整个函数。
  • 指针失败。在 C++ 中计数数组元素应该以不同的方式完成。
【解决方案4】:

像这样在 C++ 中声明一个字符串数组:char array_of_strings[][]

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

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

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

【讨论】:

  • 仅供参考,char array_of_strings[][] 不能接受 C++ 字符串,请务必先转换为 char*。 cplusplus.com/reference/string/string/c_str
  • 既然array_of_strings在header中,会不会违反单定义规则?
【解决方案5】:

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

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

【讨论】:

  • char ** 到底是什么意思?在java中,它会是一个字符串列表吗?
  • @Doomsknight:在这种情况下,是的。在第一行中,我定义了一个char* 数组。在内存中,这被布置为 3 个指针 - 一个指向“狗”,一个指向“猫”,一个指向 NULL。我可以取一个指向第一个指针的指针,并得到一个char** - 一个指向 char 的指针。当我增加它时,我移动 char** 以指向列表中的下一项 - 一个指向指向“cat”的指针的指针,然后我再次增加,并获得一个指向 NULL 指针的指针,并且我知道我已经完成了。 (
【解决方案6】:

您可以使用 Boost 范围库中的 beginend 函数来轻松找到原始数组的末端,并且与宏解决方案不同,如果您不小心应用,这将产生编译错误而不是破坏行为它指向一个指针。

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

【讨论】:

    【解决方案7】:

    您可以使用 Will Dean 的建议 [#define arraysize(ar) (sizeof(ar) / sizeof(ar[0]))] 将此处的幻数 3 替换为 arraysize(str_array) ——尽管我记得在某些特殊情况下,特定版本的 arraysize 可能会做坏事(对不起,我无法立即记住细节)。但它通常可以正常工作。

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

    【讨论】:

      【解决方案8】:

      这是一个例子:

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

      【讨论】:

        【解决方案9】:

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

        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) 但是,我们不想使用宏,因为宏可能会意外地用在指针上。该函数只能用于编译时数组。

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

        【讨论】:

          【解决方案10】:
          #include <boost/foreach.hpp>
          
          const char* list[] = {"abc", "xyz"};
          BOOST_FOREACH(const char* str, list)
          {
              cout << str << endl;
          }
          

          【讨论】:

            【解决方案11】:
            #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" ) );
            }
            

            【讨论】:

              【解决方案12】:

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-05-26
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多