【问题标题】:c ++ String array issuec++字符串数组问题
【发布时间】:2009-07-23 08:55:22
【问题描述】:

我刚从 Java 背景学习 c++。

现在只是在玩简单的类,但由于某种原因,当相同的语法在其他地方编译得很好时,以下内容将无法编译:

class CardDealer {

    private:
        string suits[4];
        string values[13];
        bool cardTaken[4][13];
        int getRand(int top);
        void getValidSuit(int *suit);
        void getValidCard(int suit,int *value);

    public:
        CardDealer();
        string dealCard();
        void resetDeck();
};

CardDealer::CardDealer(){
    suits = {"hearts", "clubs", "spades", "diamonds"};
    values = {"ace","two","three","four","five","six","seven","eight","nine","ten","jack","queen","king"};
    cardTaken = {{false,false,false,false,false,false,false,false,false,false,false,false,false},{false,false,false,false,false,false,false,false,false,false,false,false,false},
    {false,false,false,false,false,false,false,false,false,false,false,false,false},{false,false,false,false,false,false,false,false,false,false,false,false,false}};
}

显然这只是课程的一部分,所以请不要因为我错过了'}'而对我大喊大叫

编译器在遇到构造函数中的实例时会摇晃,吐出如下错误:


1>.\CardDealer.cpp(26) : error C2059: syntax error : '{'
1>.\CardDealer.cpp(26) : error C2143: syntax error : missing ';' before '{'
1>.\CardDealer.cpp(26) : error C2143: syntax error : missing ';' before '}'
1>.\CardDealer.cpp(27) : error C2059: syntax error : '{'
1>.\CardDealer.cpp(27) : error C2143: syntax error : missing ';' before '{'
1>.\CardDealer.cpp(27) : error C2143: syntax error : missing ';' before '}'
1>.\CardDealer.cpp(28) : error C2059: syntax error : '{'

第 26 行是我实例化西装的那一行 (suits = {...)

感谢各位看官,不胜感激

【问题讨论】:

    标签: c++ arrays string


    【解决方案1】:

    在 C++0x 之前,您只能在声明数组时使用聚合初始值设定项语法(即大括号)。

    请注意,此程序给出了类似的错误:

    int thing[4];
    int main ()
    {
       thing = { 0, 1, 2, 3 };
    }
    

    您必须使用有点繁琐的括号语法来初始化数组,一次一个元素。

    【讨论】:

    • 呃,太恶心了。初始化时我无法让它工作,所以我不得不走一次一次的路线。你的权利,极其乏味。谢谢!
    • 这不是唯一的解决方案,您可以将固定的初始化器存储在一个单独的数组中(可能是一个 const char* 数组),然后使用单个 std 将它们复制到类实例变量中: :copy 在构造函数中调用。
    【解决方案2】:

    我已经更正了之前的帖子:

    你可以在课堂之外像这样初始化它们:

    namespace CardDealer
    {
        static const string suits[] = {"hearts", "clubs", "spades", "diamonds"};
        static const string values[]={"ace","two","three","four","five","six","seven","eight","nine","ten","jack","queen","king"};
    
        class CardDealer 
        {    
        private:
            bool cardTaken[4][13];   
            ...
        };
    
        ...
    }
    

    在构造函数中,您可以循环初始化cardTaken

    【讨论】:

    • 我刚刚尝试了上述方法,但编译器给出了相同的错误。还是谢谢
    • 只能在类定义中初始化整数成员。
    • 积分会员是什么意思?像整数一样?或其他完全...
    • 是的,整数。这包括 bool、char、wchar_t、有符号和无符号整数类型。
    【解决方案3】:

    出现的第一个问题是,您需要suitsvalues 作为每个对象的数组还是可以在CardDealer 的所有实例之间共享它们?

    如果不是,我会将它们设为静态,然后您可以提供您尝试在其定义点使用的静态初始化语法。

    例如

    class CardDealer {
    
        private:
            static const std::string suits[4];
            static const std::string values[13];
    
        // ...
    };
    

    在其他地方的 .cc/.cpp 文件中:

    const std::string CardDealer suits[4] = { "hearts", " ... ", ... };
    const std::string CardDealer values[13] = { "ace", " ... ", ... };
    

    如果它们确实需要按类划分并且这些只是一些初始值,那么我更愿意将它们设为字符串向量,并从一些静态分配的 C 字符串中初始化它们。例如:

    class CardDealer {
    
        private:
            static const char* init_suits[4];
            static const char* init_values[13];
    
            std::vector<std::string> suits;
            std::vector<std::string> values;
    
        // ...
    };
    
    CardDealer::CardDealer()
        : suits( init_suits, init_suits + sizeof init_suits / sizeof init_suits[0] )
        , values( init_values, init_values + sizeof init_values / sizeof init_values[0] )
    {
    }
    
    const char* CardDealer::init_suits[4] = { ... };
    const char* CardDealer::init_values[13] = { ... };
    

    至于您的 cardTaken 数组,因为 0 转换为 false 您只需 default-initialize 构造函数的初始化器列表中的成员。

    CardDealer::CardDealer()
        : suits( init_suits, init_suits + sizeof init_suits / sizeof init_suits[0] )
        , values( init_values, init_values + sizeof init_values / sizeof init_values[0] )
        , cardTaken()
    {
    }
    

    【讨论】:

      【解决方案4】:

      由于我们不知道您的整个源文件,因此我们不知道第 26、27、28 行中的内容。 我猜代码:

      cardTaken = {{false,.....
      

      引发这些错误。您可以使用:

      for(int i = 0; i<4; i++)
      {
          for(int j = 0; j<13; j++)
          {
              cardTaken[i][j] = false;
          }
      }
      

      这样,您的代码更清晰、更易于理解。

      【讨论】:

      • 抱歉没有更清楚,第 26 行是我实例化 suits 的地方。为清楚起见编辑了帖子
      【解决方案5】:

      您可以在构造函数中使用类似这样的内容来消除一些乏味。

      const char* tempSuits[] = {"hearts", "clubs", "spades", "diamonds"};
      for(int i=0; i<4; ++i) suits[i] = tempSuits[i];
      

      您可以使用花括号语法来初始化 C 风格的字符串,然后您可以将其分配给 std::strings。

      你也可以在你的类中使用 C 风格的字符串作为开头(这样你就不需要循环了)。

      【讨论】:

        【解决方案6】:

        简单的解决方案:

        class CardDealer {
        
            private:
                const string suits[4];
                const string values[13];
                bool cardTaken[4][13];
                int getRand(int top);
                void getValidSuit(int *suit);
                void getValidCard(int suit,int *value);
        
            public:
                CardDealer();
                string dealCard();
                void resetDeck();
        
            private:
                static string suits_initializer[4];
                static string values_initializer[13];
        };
        
        
        CardDealer::CardDealer(){
            memcpy(suits, suits_initializer, sizeof(suits));
            memcpy(values, values_initializer, sizeof(values));
            memset(cardTaken, 0, sizeof(cardTaken));
        }
        
        string CardDealer::suits_initializer[4] = {"a","b","c","d"};
        

        这行得通,只要西装和价值观是不变的。但事实上,你需要这些作为实例变量吗?在这个例子中,静态套装和静态值对你来说就足够了。

        【讨论】:

        • 在 std::string 等类类型上使用 memcpy 非常危险!
        【解决方案7】:

        你可以使用 boost::assign :

        #include <string>
        #include <vector>
        #include <boost/assign.hpp>
        #include <boost/assign/list_of.hpp>
        #include <boost/assign/std/vector.hpp>
        
        const std::vector<std::string> my_vector_of_strings = 
        boost::assign::list_of("cat")("dog")("banana")("apple")(orange)("tuna")("salmon")("dinosaur")("blablabla")("...")("etc")("etc")("etc");
        

        有趣的是,您可以使用这个有用的库将 stl 容器声明为 const,因为代表卡片和值的数组不会改变,我可能会将它们声明为 const - 我会使用向量,因为它们'使用起来比经典数组更安全。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-10-01
          • 2020-11-05
          • 2011-07-14
          • 1970-01-01
          • 1970-01-01
          • 2023-03-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多