尝试打印出char*数组(我认为) (C++)

3

我有这两个数组:

const char *face[] =
{"Deuce", "Three", "Four", "Five",
 "Six", "Seven", "Eight", "Nine", "Ten",
 "Jack", "Queen", "King", "Ace", "\0"};

const char *suit[] = { " of Hearts", " of Clubs", " of Diamonds", " of Spades", "\0" };    

实际上,由于我在C ++方面并不那么擅长,我甚至不知道在数组或其他地方使用星号的情况...如果有人能解释一下,我会非常感激。

但是无论如何,问题是我正在尝试以以下方式打印出所有可能的带花色的牌:

for (int n = 0; n<strlen(*suit); n++){ //where strlen(*suit) should be 4
for(int i = 0; i<strlen(*face); i++){ //where strlen(*face) should be 13
        cout << endl << face[i] << suit[n] << endl;
    }
}

使用那段代码时,我的程序崩溃了。我做错了什么?(当n<4和i<13时可以工作,但如果我添加或删除数组中的项目,则希望它实际上可以正常工作)

7个回答

2
函数 strlen 接受一个 const char* 参数,即一个指向以 null 结尾的字符数组的指针。你不能使用它来计算字符串数组的长度。
相反,我建议你这样做:
const char *face[] =
    {"Deuce", "Three", "Four", "Five",
     "Six", "Seven", "Eight", "Nine", "Ten",
     "Jack", "Queen", "King", "Ace", NULL};

因此,哨兵是空指针。循环如下:

for (int i=0; face[i]; i++)
    // do something with face[i]

同样地,对于另一个数组也是一样的。
现在,所有这些说了之后,你正在用C++程序的错误方式进行操作。
  • 不要使用C字符串、字符数组指针,而是使用std::string
  • 不要使用原始数组来保存字符串,而是使用标准容器类。在你的情况下,你需要使用std::vector<std::string>
我能给你的最好建议就是忘记用C的方式去做事情,尝试学习用C++的惯用方式来编写代码。

1
是时候熟悉一下了。 - David Heffernan
没事了!这个完美地解决了,谢谢。我会开始学习向量。 - Adam
是的,在for循环中的face[i]终止测试依赖于哨兵值为null指针。 - David Heffernan

1
一些事情!你可以进行以下检查: sizeof(suit)/sizeof(suit[0]) 但它会比你需要的多运行一次,因为你确实有一个空终止字符串。所以要么从suit中删除空终止字符串并使用上述方法,要么将for更改为: for (int n = 0; strlen(suit[n]); n++) 面数组也是如此。

0
一个指针数组和一个char数组不一样。 strlen( *suit ) 返回的是face数组的第一个元素的长度,它是一个字符串。在该索引处的字符串的长度为11(包括终止字符),这就是为什么它只循环11次的原因。同样,内部循环只运行5次,因为face的第一个元素的字符串长度为6个字符长。
你应该使用std::string的向量代替:
std::vector<std::string> suit{"Deuce", "Three", "Four", "Five",
 "Six", "Seven", "Eight", "Nine", "Ten",
 "Jack", "Queen", "King", "Ace"};


std::vector<std::stirng> face{" of Hearts", " of Clubs", " of Diamonds", " of Spades"};

for (auto a : suit)
{
    for (auto b : face)
    {
        // ...
    }
}

0
 const char *face[] =
   {"Deuce", "Three", "Four", "Five",
     "Six", "Seven", "Eight", "Nine", "Ten",
      "Jack", "Queen", "King", "Ace", "\0"};

是一个字符串字面量数组。你最好将face声明如下:

string face[13]= {"Deuce", "Three", "Four", "Five",
     "Six", "Seven", "Eight", "Nine", "Ten",
     "Jack", "Queen", "King", "Ace"};

你不再需要那个 "\0",因为你不再处理 c-string(字符数组)了。

你可以对 suit 做类似的事情。

 string suit[4] = { " of Hearts", " of Clubs", " of Diamonds", " of Spades"};

您可以按如下方式打印这两个字符串数组:
  for (int n = 0; n<13; n++){ //where strlen(*face) should be 13
      for(int j = 0; j< 4; j++){ //where strlen(*suit) should be 4
          cout << endl << face[n] << suit[j] << endl;
      }
  }

但我正在尝试找到一种方法,不仅使用13和4,而是让值在我更改数组时发生变化。 - Adam
@user2280214,那么你应该遵循David的帖子。 - taocp

0

你的计数器有误

 for (int n = 0; n<4; n++){ 
    for(int i = 0; i<13; i++){ 
        cout << endl << face[i] << suit[n] << endl;
    }
 }

你也可以用这种方式来实现

 for (int n = 0; strlen(suit[n]) > 0; n++){
    for(int i = 0; strlen(face[i]) > 0; i++){
        cout << endl << face[i] << suit[n] << endl;
    }
 }

0
数组的长度不是由 strlen 给出的,因为它的元素不是 char,而是 char*。换句话说,您的数组不是一个字符串。
您需要将数组的长度存储在一个单独的变量中,或者只需使用 std::vector<const char*> face; 容器并使用 face.size()

0
你正在存储指针数组。在指针前面加上 * 可以解引用该指针并返回字符串。因此,你第一次调用 strlen(*suit) 返回 10,这将导致索引越界,从而导致程序崩溃。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接