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

输入坐标触发IndexOutOfRangeException?已加边界检查仍报错

C#战舰游戏输入坐标触发IndexOutOfRangeException异常分析

问题代码

using System;
using System.Linq;

namespace Schiffeversenken
{
    class Program
    {
        static void Main(string[] args)
        {
            // Größe der Karte
            const int width = 10;
            const int height = 10;

            // Die Karte als 2d Array von ints initialisieren
            int[,] grid = new int[width, height];

            // Schiffe platzieren (fünf Schiffe der Größe 1x1)
            for (int i = 0; i < 5; i++)
            {
                int x = new Random().Next(0, width);
                int y = new Random().Next(0, height);
                grid[x, y] = 1;
            }

            // Spiel loop
            while (true)
            {
// Karte anzeigen
                Console.WriteLine("    0 1 2 3 4 5 6 7 8 9");
                Console.WriteLine("   -------------------");
                for (int yCoord = 0; yCoord < height; yCoord++)
                {
                    Console.Write($" {yCoord} |");
                    for (int xCoord = 0; xCoord < width; xCoord++)
                    {
                        if (grid[xCoord, yCoord] == 0)
                        {
                            Console.Write(" ");
                        }
                        else if (grid[xCoord, yCoord] == 1)
                        {
                            Console.Write("X");
                        }
                        else if (grid[xCoord, yCoord] == 2)
                        {
                            Console.Write("O");
                        }
                        Console.Write("|");

                    }
                    Console.WriteLine();
                }
                Console.WriteLine("   -------------------");
                Console.WriteLine("     0 1 2 3 4 5 6 7 8 9");
                Console.WriteLine("    (X-Koordinate)");
                
                // Schiessen
                Console.WriteLine("Gib die Koordinaten für deinen Schuss ein (x y):");
                int[] input = Console.ReadLine()
                    .Split(' ')
                    .Select(s => int.Parse(s))
                    .ToArray();
                int x = input[0];
                int y = input[1];

// Prüfen, ob die Indizes innerhalb der Grenzen des Arrays liegen
                if (x >= 0 && x < width && y >= 0 && y < height)
                {
                    // Prüfen, ob ein Schiff getroffen wurde
                    if (grid[x, y] == 1)
                    {
                        Console.WriteLine("Treffer!");
                        grid[x, y] = 2;
                    }
                    else
                    {
                        Console.WriteLine("Daneben.");
                    }
                }
                else
                {
                    Console.WriteLine("Die Koordinaten liegen außerhalb des Spielfelds.");
                }


            }
        }
    }
}

报错信息

System.IndexOutOfRangeException: Index was outside the bounds of the array.
at Schiffeversenken.Program.Main(String[] args) in C:\Users\timoa\RiderProjects\Battleships\Battleships\Program.cs:line 64

异常原因

你添加的边界检查是针对grid数组的坐标范围,但异常并非来自grid数组访问,而是来自input数组的索引访问。

当用户输入不符合预期格式时(比如只输入一个数字、输入非数字内容、输入空行、输入多个空格分隔的多余内容),会出现以下情况:

  1. Console.ReadLine().Split(' ')得到的数组长度不等于2,比如输入空行时数组可能为空,输入一个数字时数组长度为1
  2. 此时直接访问input[0]或input[1]就会触发IndexOutOfRangeException
  3. 另外,Select(s => int.Parse(s))还会在输入非数字时触发FormatException,这也是潜在问题

解决方法

需要在访问input数组前,先验证输入的格式有效性,包括:

  1. 检查输入是否为空
  2. 检查分割后的数组是否正好有两个元素
  3. 检查两个元素能否成功转换为整数
  4. 最后再进行坐标边界检查

修改后的射击逻辑代码如下:

// Schiessen
Console.WriteLine("Gib die Koordinaten für deinen Schuss ein (x y):");
string inputLine = Console.ReadLine();

// 检查输入是否为空
if (string.IsNullOrWhiteSpace(inputLine))
{
    Console.WriteLine("Bitte gib gültige Koordinaten ein.");
    continue;
}

// 分割输入,移除空项(处理多个空格的情况)
string[] inputParts = inputLine.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);

// 检查是否正好两个坐标
if (inputParts.Length != 2)
{
    Console.WriteLine("Bitte gib genau zwei Koordinaten getrennt durch Leerzeichen ein.");
    continue;
}

// 尝试转换为整数,失败则提示
if (!int.TryParse(inputParts[0], out int x) || !int.TryParse(inputParts[1], out int y))
{
    Console.WriteLine("Bitte gib nur ganze Zahlen für die Koordinaten ein.");
    continue;
}

// Prüfen, ob die Indizes innerhalb der Grenzen des Arrays liegen
if (x >= 0 && x < width && y >= 0 && y < height)
{
    // Prüfen, ob ein Schiff getroffen wurde
    if (grid[x, y] == 1)
    {
        Console.WriteLine("Treffer!");
        grid[x, y] = 2;
    }
    else
    {
        Console.WriteLine("Daneben.");
    }
}
else
{
    Console.WriteLine("Die Koordinaten liegen außerhalb des Spielfelds.");
}

额外优化点

你的战舰放置逻辑存在重复坐标的可能(多次生成相同位置导致战舰数量不足5艘),且每次循环创建Random实例会因为系统时钟精度问题导致重复随机数,建议修改为:

// Schiffe platzieren (fünf Schiffe der Größe 1x1)
Random random = new Random();
for (int i = 0; i < 5; i++)
{
    int x, y;
    // 循环直到找到未被占用的位置
    do
    {
        x = random.Next(0, width);
        y = random.Next(0, height);
    } while (grid[x, y] == 1);
    grid[x, y] = 1;
}

内容的提问来源于stack exchange,提问作者timosaiya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 11:16:01