【问题标题】:Classes in C++ and Printing CharC++ 中的类和打印字符
【发布时间】:2021-08-26 07:17:25
【问题描述】:

我知道肯定遗漏了一些明显的东西,但我仍然在理解课程方面遇到了很多麻烦。我有一个指针,我确定那是错误的,但我不知道怎么做。此外,当我尝试打印其中一个变量时,它只显示第一个字符而不是两个字符,我不知道如何解决。

class Pieces
{
    public:
        char P1;
        char P2;
        char P3;
        char P4;
        char P5;
        char P6;
        char P7;
        char P8;
        char P9;
        void Board(char P1, char P2, char P3, char P4, char P5, char P6, char P7, char P8, char P9);
        void Board();
        
};

void Pieces::Board()
{
    cout << "    A   B   C \n";
    cout << " 1  B1  B2  B3\n";
    cout << " 2  .   .   . \n";
    cout << " 3  W1  W2  W3\n";
}

void Pieces::Board(char P1, char P2, char P3, char P4, char P5, char P6, char P7, char P8, char P9)
{
    cout << "    A   B   C \n";
    //cout << " 1  ", P1, "  ", P2, "  ", P3, "\n";
    cout << P1;
    cout << P1;
    cout << "\n";
    //cout << " 2  ", P4, "  ", P5, "  ", P6, "\n";
    //cout << " 3  ", P7, "  ", P8, "  ", P9, "\n";
}

int main()
{
    Pieces IDK;
    IDK.P1 = *"B1";
    IDK.P2 = *"B2";
    IDK.P3 = *"B3";
    IDK.P4 = *". ";
    IDK.P5 = *". ";
    IDK.P6 = *". ";
    IDK.P7 = *"W1";
    IDK.P8 = *"W2";
    IDK.P9 = *"W3";

    cout << IDK.P1;

    IDK.Board();
    IDK.Board(IDK.P1, IDK.P2, IDK.P3, IDK.P4, IDK.P5, IDK.P6, IDK.P7, IDK.P8, IDK.P9);
}

【问题讨论】:

  • 代码应该做什么?什么是预期的输出?实际输出是多少?
  • 请注意char 是单个字符而不是字符串,您希望*"B1" 做什么?
  • IDK.P1 = *"B1"; 将字符“B”分配给成员 P1。如果 arr 是一个数组变量,你总是可以写 arr[0] 而不是 *arr

标签: c++ class char cout


【解决方案1】:

我尽量让这件事变得简单:

IDK.P1 = *"B1";

在这一行中,您将多个字符分配给单个字符。 P1char 类型,它只包含一个字符。 char 是一种包含单个字节的类型,意味着是一个 ASCII 编码字符。 B1 是两个字符。

在 C 风格的编程中,您将使用已弃用的 char 数组来保存多个字符 (char*)。这将是一个以终止符号 (\0) 结尾的数组(内存中连续的几个值)。
但请注意,我编写 C 风格是有原因的——在 C++ 中,你不会使用它。

现在,对于语法*"B1",它的作用是:"B1" 以指向 char 数组的指针开始。星号取消引用该指针。由于指向数组的指针指向它的第一个元素,因此取消引用会为您提供该元素,该元素在您的情况下包含值 B。
像这样的语法非常不寻常,我不知道你是如何使用它的。

无论如何,在一个char 中存储两个字符是不可能的。
你可能想简单地过去

std::string P1;

在你的课堂上,并像这样分配它

IDK.P1 = "B1";

我注意到的另一件事是你的方法

void Pieces::Board(char P1, char P2, char P3, char P4, char P5, char P6, char P7, char P8, char P9)
{
    cout << "    A   B   C \n";
    //cout << " 1  ", P1, "  ", P2, "  ", P3, "\n";
    cout << P1;
    cout << P1;
    cout << "\n";
    //cout << " 2  ", P4, "  ", P5, "  ", P6, "\n";
    //cout << " 3  ", P7, "  ", P8, "  ", P9, "\n";
}

不分配任何值。它接受的参数在调用后被遗忘。它确实不会改变你的类的成员变量。我怀疑你似乎认为同名=被超越,如果是这样,那不是这样的。


至于这个:

    char P1;
    char P2;
    char P3;
    char P4;
    char P5;
    char P6;
    char P7;
    char P8;
    char P9;

如果你写了一个程序,你发现你做了一些非常重复的事情,比如这样,那么你通常是在以一种繁琐的方式去做。
在这种情况下,您可以简单地使用一个数组:

std::array<char, 9> P;

然后像这样处理它

Pieces pieces;
pieces.P.at(0) = 'a';

IDK.Board(IDK.P1, IDK.P2, IDK.P3, IDK.P4, IDK.P5, IDK.P6, IDK.P7, IDK.P8, IDK.P9);

这一行是您的代码的另一件很奇怪的事情。您使用它自己的成员变量调用该对象。它已经知道它自己的成员。此外,Board 对于打印数据的东西来说是个坏名字。在动作完成后命名。试试这个:

void Pieces::print_board() { cout

(我在这里也用流操作符替换了逗号。)


这是你的代码的返工:

class Board // I renamed it to Board, because that is what it represents
{
public:

    Board() {} 
    // constructor that already takes in the state of the board,
    // using a member initializer list,
    // see https://en.cppreference.com/w/cpp/language/constructor
    Board(const std::array<std::string, 9>& pieces) : pieces(pieces) {} 
    void print() const; // if something prints, let's name it like that

    std::array<std::string, 9> pieces;  
};

void Board::print() const
{
    // I use for-loops here because while you could do your block right now,
    // it would become really cumbersome in a bigger grid
    
    cout << "    A   B   C \n";
    for(size_t i=0; i<3; i++)
    {
        cout << " " << (i+1) << "  ";
        for(size_t j=0; j<3; j++)
        {
            cout << pieces.at(i*3+j) << "  ";
        }
        cout << endl;
    }
}

int main()
{
    Board board({"B1", "B2", "B3", ". ", ". ", ". ", "W1", "W2", "W3"});
    board.print();

    /* alternatively:
    Board board;
    board.pieces.at(0) = "B1";
    ...
    board.print();
    */
}

(试一试:http://www.cpp.sh/4vv3s

请注意,我们可能要添加检查是否所有“片段”的长度为 2,否则打印会错位。或者更好的是,为片段使用适当的类型,例如enum class,以及将其值转换为字符串的函数。

由于这些片段形成了一个网格,我们可能希望使用二维数组std::array&lt;std::array&lt;std::string, 3&gt;, 3&gt; pieces;board.pieces.at(0).at(0) = "B1"; 之类的访问器。但我暂时忽略了它。

如果您需要动态大小,请使用std::vector 而不是std::array

【讨论】:

  • 谢谢,抱歉我的语法不好。我对指针真的很困惑,只想回到 R,但这不是主要要求的方式
  • @KatieOsadczuk 是的,当您第一次使用指针时,它们很容易让人感到困惑。它们也非常有用,使用后很容易理解。尽管在您的情况下,这不是进入指针的正常方法。 Char 数组是一个非常具体的东西,而不是指针的一个好的开始。我的建议是尝试编写一些指针结构作为练习,例如链表。
【解决方案2】:

char 只是放置一个字符。如果需要多个字符,可以使用 char 数组或 std::string。当您使用双引号 "AB" 时,它表示一个 const char* 或常量字符数组。您只能在 char 类型变量中保留单个字符或 1 个字节的数据。这就是为什么你只看到第一个字符。您用单引号 'A' 描述了一个字符。

【讨论】:

    【解决方案3】:

    在板子功能中

    cout << P1
    cout << P2
    cout << P3
    

    去做

    【讨论】:

      【解决方案4】:

      我不会谈论错字,因为已经有其他答案可以解决它,我将专注于对我来说最大的问题:你没有正确使用类。

      课程的重点是拥有“可以自己做所有事情的东西”,所以你不应该不断地给他们所有他们需要的数据,你想给他们一次数据,然后永远不必考虑它再次。对于您的应用程序,您可以像这样构建您的类:

      1. 定义一个可以记住 P1..9 的类
      2. 为该类定义一个构造函数,并在其中为其提供所有数据
      3. 为该类定义方法,以便您可以打印其中已有的数据

      它可能看起来像这样:

      #include <string>
      
      class Board
      {
          public:
              Board();
              Board(char P1, char P2, char P3, char P4, char P5, char P6, char P7, char P8, char P9);
              void printBoard();
      
          private:
              char P1;
              char P2;
              char P3;
              char P4;
              char P5;
              char P6;
              char P7;
              char P8;
              char P9;
      };
      
      Board::Board()
      {
          P1 = P2 = P3 = P4 = P5 = P6 = P7 = P8 = P9 = 0;
      }
      
      Board::Board(char piece1, char piece2, char piece3, char piece4, char piece5, char piece6, char piece7, char piece8, char piece9)
      {
          P1 = piece1;
          P2 = piece2;
          P3 = piece3;
          P4 = piece4;
          P5 = piece5;
          P6 = piece6;
          P7 = piece7;
          P8 = piece8;
          P9 = piece9;
      }
      
      void Board::printBoard()
      {
          std::string val;
      
          cout << "    A   B   C \n";
      
          val = " 1  ";
          if(P1 == 0)
              val += "B1";
          else
              val += std::to_string(P1);
      
          if(P2 == 0)
              val += "B2";
          else
              val += std::to_string(P2);
      
          if(P3 == 0)
              val += "B3";
          else
              val += std::to_string(P3);
      
          val += '\n';
          cout << val;
      
      
          val = " 2  ";
          if(P4 == 0)
              val += ". ";
          else
              val += std::to_string(P4);
      
          if(P5 == 0)
              val += ". ";
          else
              val += std::to_string(P5);
      
          if(P6 == 0)
              val += ". ";
          else
              val += std::to_string(P6);
      
          val += '\n';
          cout << val;
      
      
          val = " 3  ";
          if(P7 == 0)
              val += "W1";
          else
              val += std::to_string(P7);
      
          if(P8 == 0)
              val += "W2";
          else
              val += std::to_string(P8);
      
          if(P9 == 0)
              val += "W3";
          else
              val += std::to_string(P9);
      
          val += '\n';
          cout << val;
      }
      

      然后你会像这样使用它:

      int main ()
      {
          Board a;
          Board b('a','b','c','d','e','f','g','h','i');
      
          a.printBoard();
          b.printBoard();
      
          return 0;
      }
      

      编辑:尽管我使用了您的方式,但请注意 char 数组或 std::string 对象可以使代码更短且更易于管理。

      【讨论】:

        猜你喜欢
        • 2021-11-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-20
        • 1970-01-01
        • 2013-06-01
        • 1970-01-01
        相关资源
        最近更新 更多