Как предотвратить FormatException и IndexOutOfRangeException?

Этот код создает исключение формата, когда пользователь вводит неправильный ввод при преобразовании строки в int. Он также не достигает желаемого вывода «Все места первого класса забронированы», когда было продано 32 билета, он просто выдает исключение индекса вне допустимого диапазона. Любая помощь в этом будет принята с благодарностью. Спасибо.

class FirstClassCompartment
{ 
    public void FirstClassTickets()
    {
        bool[] seats = new bool[32];
        List<int> seatsBooked = new List<int>();
        int completeBooking = 0;
        bool quit = false;
        string ticketAmount = "";
        int firstClassSeat = 0;
        int convertedTicketAmount;
        {
            Groups firstClass = new Groups();
            Console.Clear();
            Console.WriteLine("\nWelcome to the First Class booking menu");
            Console.WriteLine("");
            Console.WriteLine("Please enter the amount of tickets you would like to book");
            ticketAmount = Console.ReadLine();
            Console.Clear();
            Console.WriteLine("\nFirst Class booking menu");
                    convertedTicketAmount = Convert.ToInt32(ticketAmount);
                    ticketAmount = firstClass.NumberInGroupFirstClassWest;
        }

        do
        {
            Console.Clear();
            Console.WriteLine("\nFirst Class booking menu");
            Console.WriteLine("");
            Console.WriteLine("Please press 1 to complete your first class booking");
            completeBooking = Int32.Parse(Console.ReadLine());

            switch (completeBooking)
            {
                case 1:

                    if (seatsBooked.Count == 0)
                    {
                        firstClassSeat++;
                        seats[firstClassSeat] = true;
                        seatsBooked.Add(firstClassSeat);
                    }
                    else
                    {

                        do
                        {
                            firstClassSeat++;
                            if (!seatsBooked.Contains(firstClassSeat))
                            {
                                seats[firstClassSeat] = true;

                            }
                        }
                        while (seatsBooked.Contains(firstClassSeat) && seatsBooked.Count < 32);
                        if (seatsBooked.Count < 32)
                        {
                            seatsBooked.Add(firstClassSeat);
                        }
                    }
                    if (seatsBooked.Count > 32)
                    {
                        Console.WriteLine("All seats for first class have been booked");
                        Console.WriteLine("Please press enter to continue...");

                    }
                    else
                    {
                        Console.WriteLine("Your seat: {0}", firstClassSeat + 1);
                        Console.WriteLine("Please press enter to continue...");

                    }
                    Console.ReadLine();
                    break;
                default:
                    Console.WriteLine("\nPlease enter a valid input");
                    quit = true;
                    break;
            }
        } while (!quit);
    }
}

person JamesAH    schedule 22.12.2015    source источник
comment
Вам нужно использовать Int.TryParse() и отображать пользователю ошибку, если она возвращает false.   -  person Paul Abbott    schedule 23.12.2015


Ответы (2)


Вам необходимо использовать Int32.TryParse и проверьте возвращенный bool.

Посмотрите на логику в вашем операторе switch, вы обрабатываете только 1 бронирование. Что, если пользователь бронирует 2 места?
Редактировать: извините, только что понял, что оператор switch должен обрабатывать меню, а не количество заказов

Вам нужен список int, а также массив bool, чтобы отслеживать, сколько мест было забронировано? Не могли бы вы просто использовать старый добрый int, например. numberOfSeatsBooked? Тогда вы можете сделать numberOfSeatsBooked += convertedTicketAmount;

person Ian    schedule 22.12.2015
comment
Я еще не совсем зашел так далеко, я просто хотел сначала избавиться от этих исключений. Кроме того, список, кажется, начинается с 2 (первый проданный билет - 2). Есть ли какая-то причина для этого, насколько вы можете видеть? - person JamesAH; 23.12.2015
comment
Избавление от массивов и списков избавит от IndexOutOfRangeException, а использование TryParse избавит от NumberFormatException. Помните, что список буквально таков, представьте, что вы пишете его на листе бумаги. Теперь вы говорите об размере списка или первом элементе. Если вы продаете 2 билета, ваш код seatsBooked.Add(firstClassSeat); добавляет 2 билета в список. Список size будет равен 1, а единственным элементом в списке будет номер 2. - person Ian; 23.12.2015
comment
Я понимаю логику этого, но я не уверен в синтаксисе, который мне нужно использовать для отслеживания забронированных мест с использованием массива логических значений? - person JamesAH; 23.12.2015
comment
Массив bool нужен только в том случае, если вы заинтересованы в отслеживании отдельных мест (чего вы сейчас не делаете). Если вам нужно отслеживать только количество мест, простой int намного проще. - person Ian; 23.12.2015

Я бы сделал это совсем по-другому. У вас должен быть класс для мест, содержащий логическое значение для забронировано, и повторять его, а не случайный массив книг, который может быть или не быть связан со случайным списком забронированных мест и количеством забронированных мест. Вот небольшой пример:

public class Seat
{
    public int SeatNo { get; set; }
    public bool FirstClass { get; set ; }
    public bool Booked { get; set; } // could actually be an instance of a booking info class including name and ticket id, etc.
}

public class Flight
{
    public List<Seat> Seats = new List<Seat>();
    private int _lastSeat = 0;
    public void AddSeats(int num, bool firstClass)
    {
        for (int i = 0; i < num; i++)
        {
            _lastSeat++;
            Seats.Add(new Seat { SeatNo = num, FirstClass = firstClass });
        }
    }

    public int BookNextAvailableSeat(bool firstClass)
    {
        foreach (Seat seat in Seats.AsQueryable().Where(x => x.FirstClass == firstClass)
        {
            if (!seat.Booked)
            {
                seat.Booked = true;
                return seat.SeatNo;
            }
        }
        return null;
    }
}

Тогда ваш:

case 1:
    int booking = flight.BookNextAvailableSeat(true);
    if (booking != null)
        Console.WriteLine("Your seat: {0}", booking);
    else
        Console.WriteLine("All seats for first class have been booked");
    Console.WriteLine("Please press enter to continue...");
    break;

Конечно, вам нужно создать экземпляр полета и добавить 32 места, используя:

Flight flight = new Flight();
flight.AddSeats(32, true);
person Steve Harris    schedule 23.12.2015