You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++游戏设置函数循环异常:正确输入后仍重复触发列输入

C++游戏设置程序循环异常修复问题

我编写的C++游戏设置程序出现循环异常:输入正确的行数、列数和僵尸数量后,程序未按预期结束设置流程,反而持续循环。相关代码及输出情况如下:

主程序代码

#include <iostream>
#include <stdlib.h>
#include "boardsetting.h"
using namespace std;

main()
{
    int x_dim = 19;
    int y_dim = 5;
    int num_zombie = 1;
    std::string answer;
    // default
    cout << "Default Game Settings" << endl;
    cout << "-----------------------" << endl;
    cout << "Board Rows     : " << y_dim << endl;
    cout << "Board Columns  : " << x_dim << endl;
    cout << "Zombie Count   : " << num_zombie << endl;

    int i = 0;
    while (i == 0)
    {
        cout << "\nDo you wish to change the game settings (y/n)? => ";
        cin >> answer;
        system("CLS");
        if (answer == "y")
        {
            Board_Setting();
            i = i + 1;
        }
        else if (answer == "n")
        {
            // Game DashBoard
            i = i + 1;
        }
        else
        {
            cout << "Invalid input. Please try again." << endl;
            i = i + 0;
        }
    }
}

board_setting.h头文件代码

// Header file board_setting.h
#include <iostream>
#include <stdlib.h>
#include <limits>

// system to accept only numeric number only
const auto Accept_Num = std::numeric_limits<std::streamsize>::max();
void Board_Setting()
{
    int x_dim = 0;
    int y_dim = 0;
    int num_zombie = 0;

    bool test_row = false;
    std::cout << "Board Settings" << std::endl;
    std::cout << "----------------" << std::endl;
    while (!test_row)
    {
        std::cout << "Enter rows => ";
        std::cin >> y_dim;
        if (!y_dim)
        {
            std::cout << "Please enter numeric_number. Please try again!" << std::endl;
            std::cin.clear();
            std::cin.ignore(Accept_Num, '\n');
            test_row = false;
            std::cout << "\n";
        }
        else if (y_dim % 2 == 0)
        {
            std::cout << "You have entered even number! Please try again!" << std::endl;
            std::cout << "\n";
        }
        else
        {
            while (y_dim % 2 != 0)
            {
                bool test_col = false;
                while (!test_col)
                {
                    std::cout << "Enter columns => ";
                    std::cin >> x_dim;
                    if (!x_dim)
                    {
                        std::cout << "Please enter numeric value. Please try again!" << std::endl;
                        std::cin.clear();
                        std::cin.ignore(Accept_Num, '\n');
                        test_col = false;
                        std::cout << "\n";
                    }
                    else
                    {
                        test_col = true;
                        bool test_zombie = false;
                        std::cout << "\nZombie Settings" << std::endl;
                        std::cout << "------------------" << std::endl;
                        // to allow user to reenter when input is not numeric number.
                        while (!test_zombie && test_col)
                        {
                            std::cout << "Enter number of zombies => ";
                            std::cin >> num_zombie;
                            if (num_zombie)
                            {
                                std::cout << "\nSetting Updated." << std::endl;
                                test_zombie = true;
                                test_col = true;
                                system("pause");
                            }
                            else
                            {
                                std::cout << "Invalid input. Please try again!" << std::endl;
                                std::cin.clear();
                                std::cin.ignore(Accept_Num, '\n');
                                test_zombie = false;
                            }
                        }
                    }
                }
            }
        }
    }
}

期望输出

Board Settings
Enter rows => 3
Enter columns => 5

Zombie Settings
------------------
Enter number of zombies => 2

Setting Updated.
Press any key to continue . . .

实际输出

Board Settings
Enter rows => 3
Enter columns => 5

Zombie Settings
------------------
Enter number of zombies => 2

Setting Updated.
Press any key to continue . . .
Enter columns =>

程序开始持续循环。

请问如何修复该循环异常,使输入正确参数后程序能正常结束设置流程?


解决方案

问题根源

  1. 内层无限循环:输入有效奇数行数后,进入while (y_dim % 2 != 0)循环,由于y_dim值不会改变,这个循环会无限执行,导致重复要求输入列数。
  2. 外层循环未终止:即使所有参数输入正确,外层的while (!test_row)循环始终没有将test_row设为true,无法退出设置流程。
  3. 输入验证逻辑错误:用if (!y_dim)判断输入是否为数字的方式有误,会把0误判为非数字输入,应该检查cin的状态。

修复步骤

1. 删除无意义的内层循环

移除while (y_dim % 2 != 0)循环,因为行数已经验证为奇数,无需重复执行。

2. 完成设置后终止外层循环

在僵尸数量输入正确后,将test_row设为true,让外层循环退出。

3. 修正输入验证逻辑

将if (!y_dim)改为if (std::cin.fail()),正确判断输入是否为有效数字;同时增加对正整数的验证,避免输入0或负数。

修正后的board_setting.h代码

// Header file board_setting.h
#include <iostream>
#include <stdlib.h>
#include <limits>

// system to accept only numeric number only
const auto Accept_Num = std::numeric_limits<std::streamsize>::max();
void Board_Setting()
{
    int x_dim = 0;
    int y_dim = 0;
    int num_zombie = 0;

    bool test_row = false;
    std::cout << "Board Settings" << std::endl;
    std::cout << "----------------" << std::endl;
    while (!test_row)
    {
        std::cout << "Enter rows => ";
        std::cin >> y_dim;
        if (std::cin.fail())
        {
            std::cout << "Please enter numeric number. Please try again!" << std::endl;
            std::cin.clear();
            std::cin.ignore(Accept_Num, '\n');
            std::cout << "\n";
        }
        else if (y_dim <= 0 || y_dim % 2 == 0)
        {
            std::cout << "You have entered invalid number! Must be positive odd number. Please try again!" << std::endl;
            std::cout << "\n";
        }
        else
        {
            bool test_col = false;
            while (!test_col)
            {
                std::cout << "Enter columns => ";
                std::cin >> x_dim;
                if (std::cin.fail())
                {
                    std::cout << "Please enter numeric value. Please try again!" << std::endl;
                    std::cin.clear();
                    std::cin.ignore(Accept_Num, '\n');
                    std::cout << "\n";
                }
                else if (x_dim <= 0)
                {
                    std::cout << "Columns must be positive number. Please try again!" << std::endl;
                    std::cout << "\n";
                }
                else
                {
                    test_col = true;
                    bool test_zombie = false;
                    std::cout << "\nZombie Settings" << std::endl;
                    std::cout << "------------------" << std::endl;
                    // to allow user to reenter when input is not numeric number.
                    while (!test_zombie)
                    {
                        std::cout << "Enter number of zombies => ";
                        std::cin >> num_zombie;
                        if (std::cin.fail() || num_zombie <= 0)
                        {
                            std::cout << "Invalid input. Must be positive numeric number. Please try again!" << std::endl;
                            std::cin.clear();
                            std::cin.ignore(Accept_Num, '\n');
                        }
                        else
                        {
                            std::cout << "\nSetting Updated." << std::endl;
                            test_zombie = true;
                            test_row = true; // 终止外层循环
                            system("pause");
                        }
                    }
                }
            }
        }
    }
}

额外优化建议

  • 给main()函数添加返回值,改为int main()并返回0,符合C++标准。
  • 将Board_Setting()的实现移到.cpp文件中,头文件只保留函数声明,避免重复编译问题。
  • 把输入验证逻辑封装成独立函数,减少代码重复。

内容的提问来源于stack exchange,提问作者FL C.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 22:20:41