C++;异常std::长度_有时出错? 我试图用C++写一个简单的刽子手游戏。这个游戏大部分都能运行,但有时当我调试它时,会出现异常std::length\u错误。通常在用户输入选择之后。我在这里写了相关的代码,因为Stack Overflow说我的文章大部分都是代码。如果需要的话,我会提供剩下的。主要代码、变量和函数声明: #include "stdafx.h" #include <iostream> #include <string> #include <ctime> #include <stdlib.h> using namespace std; void game(int choice); void check(char letter, string word); bool check_win(string word); char guessed[30]; int guessCount = 0, tries = 0; int main() { int choice, sentinel; cout << "Welcome to Phobez's Hangman game!" << endl; cout << "=================================" << endl; cout << "Guess a word which is represented by a row of dashes, representing each letter of the word." << endl; cout << "Pick a Topic" << endl; cout << "1. Animals\n2. Colours\n3. Days of the Week\n4. Months\n5. Body Parts\n6. Numbers" << endl; cout << "Choice: "; cin >> choice; game(choice); system("pause"); return 0; } #包括“stdafx.h” #包括 #包括 #包括 #包括 使用名称空间std; 无效游戏(整数选择); 无效检查(字符字母、字符串字); bool check_-win(字符串字); char猜测[30]; int guessCount=0,trys=0; int main() { int选择,哨兵; cout

C++;异常std::长度_有时出错? 我试图用C++写一个简单的刽子手游戏。这个游戏大部分都能运行,但有时当我调试它时,会出现异常std::length\u错误。通常在用户输入选择之后。我在这里写了相关的代码,因为Stack Overflow说我的文章大部分都是代码。如果需要的话,我会提供剩下的。主要代码、变量和函数声明: #include "stdafx.h" #include <iostream> #include <string> #include <ctime> #include <stdlib.h> using namespace std; void game(int choice); void check(char letter, string word); bool check_win(string word); char guessed[30]; int guessCount = 0, tries = 0; int main() { int choice, sentinel; cout << "Welcome to Phobez's Hangman game!" << endl; cout << "=================================" << endl; cout << "Guess a word which is represented by a row of dashes, representing each letter of the word." << endl; cout << "Pick a Topic" << endl; cout << "1. Animals\n2. Colours\n3. Days of the Week\n4. Months\n5. Body Parts\n6. Numbers" << endl; cout << "Choice: "; cin >> choice; game(choice); system("pause"); return 0; } #包括“stdafx.h” #包括 #包括 #包括 #包括 使用名称空间std; 无效游戏(整数选择); 无效检查(字符字母、字符串字); bool check_-win(字符串字); char猜测[30]; int guessCount=0,trys=0; int main() { int选择,哨兵; cout,c++,exception,C++,Exception,Atif(word[i]==gustized[j])j索引可能会越界,因为它被j数组。siz()/Cyt >而不是 SIEZOF(数组)/siZeof(数组[0)] /Cube >要短得多,更可读。@ GLUWILLITET siZOF(数组)/siZeof(数组[0)]将在特定的代码示例中起作用。但是这非常棘手,并且是错误的常见原因,因为当您将数组作为参数传递时,数组的大小将是指针的大小(例如:)。这就是为什么首选std::array或更灵活的std::vector。 <string

At
if(word[i]==gustized[j])
j
索引可能会越界,因为它被
j
而不是
猜测的
长度所限制。同样值得将
猜测的
类型更改为
::std::string
。因此循环条件需要更改为类似的内容

for
(
    ::std::string::size_type guessed_symbol_index = 0;
    guessed.length() != guessed_symbol_index;
    ++guessed_symbol_index
) 
...
if (word[i] == guessed[guessed_symbol_index]) {
所有开关盒中都填充了可能导致越界访问的行,例如
animal[(rand()%17)-1];
如果
rand
返回17。此外,您可能会意外设置错误的数组大小(使用幻数是不好的)。您应该将这些数组重新定义为

::std::array<::std::string, 7> day = { "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday" };
::std::array day={“周一”、“周二”、“周三”、“周四”、“周五”、“周六”、“周日”};
然后正确提取长度:

day[static_cast<::std::size_t>(rand()) % day.size()];
day[static_cast(rand())%day.size();

使用调试器,速度会更快。但这里是演绎方式:

  • 当有人试图超出某些对象的实现定义的长度限制时抛出,例如
    字符串的
    max_size
    向量的
    max_size
    (请注意,这不是超出范围的问题,而是存储对象所需大小的问题)

  • 您不使用
    vector
    ,您仅有的字符串是
    word
    word
    唯一可能超出存储限制的地方是您对其进行赋值时。但是限制太大,数组中的小词无法触发此限制

  • 因此,这意味着您的数组访问不会访问您认为它访问的元素。因此,下标肯定有问题

  • 在这里,我们将返回一个介于0和
    RAND_MAX
    之间的值。使用模,您可以确保上限是正确的。但是如果
    RAND()
    返回0会怎么样?然后访问元素
    -1
    ,这是未定义的行为,也是意外崩溃的根本原因

  • 如何解决它?

    更改下标表达式。例如,在
    animal[]
    中,您有17个元素,索引范围从0到16。因此,如果您将下标更改为
    rand()%17
    ,您将得到一个介于0和16之间的数字,该数字保证在预期范围内

    您还可以使用向量而不是数组,这样可以避免手动计算其中的元素:

     <string> animal{ "cat", "dog", "horse", "elephant", "duck", "turtle", "bird", "crab", "spider", "bear", "pig", "penguin", "mouse", "rabbit", "lion", "monkey", "bull"};
     ...
     word = animal[ rand()%animal.size() ]; // asuming that the vector is not empty :-)
    
    动物{“猫”、“狗”、“马”、“象”、“鸭”、“龟”、“鸟”、“蟹”、“蜘蛛”、“熊”、“猪”、“企鹅”、“老鼠”、“兔子”、“狮子”、“猴子”、“公牛”};
    ...
    word=animal[rand()%animal.size()];//假设向量不是空的:-)
    

    另外:
    strlen(word.c_str())
    可以替换为
    word.size()

    不要发布整个程序供其他人调试。首先,将程序简化为相关部分,创建一个。您可能需要这样做,但这将有助于找出错误。@StoryTeller好的,我会先试试。谢谢!@gliwibilt此索引表达式中的索引word=animal[(rand()%17)-1];可以等于-1。你在一个地方也有
    animal[(rand()%17)-1];
    在另一个地方有
    animal[(rand()%18)-1];
    。顺便说一句,不能
    rand()%x
    变成0吗?@VladfromMoscow我明白了…我被教导rand()从1开始,所以我加了-1,但似乎我被教导错了。-。我不知道rand()从0开始,我被教导它从1开始。-。我想我被教导错了。非常感谢!这修复了它!我还没有学到很多关于向量的知识,所以我会继续读下去。再次感谢!对不起,我对这个有点陌生,但什么是幻数?我明白你所说的循环条件是什么意思,非常感谢!我甚至没有意识到那个。@gliwidelt请参见。在
    [(rand()%17)-1];
    17是一个幻数,应该是数组大小。如果我要通过sizeof(array)/sizeof(array[0])获得数组大小,我刚刚读到了这一点它会工作吗?因为这个数组的内容是由几个字符串组成的字符串characters@gliwidilt典型的C样式数组不应该在C++中使用。也写代码>数组。siz()/Cyt >而不是<代码> SIEZOF(数组)/siZeof(数组[0)] /Cube >要短得多,更可读。@ GLUWILLITET <代码> siZOF(数组)/siZeof(数组[0)]
    将在特定的代码示例中起作用。但是这非常棘手,并且是错误的常见原因,因为当您将数组作为参数传递时,数组的大小将是指针的大小(例如:)。这就是为什么首选
    std::array
    或更灵活的
    std::vector
     <string> animal{ "cat", "dog", "horse", "elephant", "duck", "turtle", "bird", "crab", "spider", "bear", "pig", "penguin", "mouse", "rabbit", "lion", "monkey", "bull"};
     ...
     word = animal[ rand()%animal.size() ]; // asuming that the vector is not empty :-)