Вложенный оператор if/else внутри цикла for работает не так, как ожидалось

#c# #for-loop #if-statement

Вопрос:

Я не могу определить, где моя ошибка в моем IF/ELSE заявлении, вложенном в мой for цикл. Я попытался использовать while цикл, чтобы заставить мое IF/ELSE заявление работать, но оно сработало не так, как ожидалось.

Даже мое Console.Writeline заявление не может охватить правильную цену и размер.

Мой код:

 static void Main(string[] args)
{
    string[] size = { "S", "M", "L", "X"};
    decimal[] price = { 6.99M, 8.99M, 12.50M, 15.00M};

    Console.WriteLine("Please enter a pizza size : ");
    string pizzaSize = Console.ReadLine();

    int i;

    for (i = 0; i < size.Length; i  )
    {
        if (size[i] == pizzaSize)
        {
            Console.WriteLine("Your pizza size is "   pizzaSize   ". The price is "   price[i].ToString("C"));
        } else
        {
            Console.WriteLine("Please enter a valid pizza size");
            return;
        }
    }
    Console.ReadKey();
}
 

Комментарии:

1. Вы запустили свой код в отладчике? Что происходит, что вы наблюдаете? Примечание.вы можете использовать окно «Немедленное» в Visual Studio, чтобы проверить, например, значение размера[i] при установке точки останова в операторе if.

2. Если вы введете, например M , в качестве выбранного размера пиццы, первой проверкой будет if ("S" == "M") , что очевидно false . Таким образом, вы попадете в else ветвь на первой итерации, что приведет к return немедленному запуску функции. Что, в Main свою очередь, означает, что программа завершается. Кроме того, учтите, что сравнение строк с == не рекомендуется, и сравнения также чувствительны к регистру, поэтому "M" == "m" вернутся false

3. @ADyson Да, извини за это. Если вводимые пользователем данные не совпадают с размером, будет выполнена инструкция об ошибке

4. return; в этом else пункте мне кажется странным.

5. Меня очень давно учили, что функция должна иметь только одну точку выхода. Это помогает структурировать код и избавляет от многих головных болей при попытке отладки.

Ответ №1:

Если значение pizzaSize равно "L" , то в for цикле первой проверкой будет if ("L" == "M") то , что false затем else ветвь выполняется на первой итерации , что return; в else предложении приводит к немедленному возвращению функции. поэтому, если вы хотите проверить, является ли pizzaSize значение допустимым, вы можете использовать следующее решение:

 static void Main(string[] args)
    {
        string[] size = { "S", "M", "L", "X"};
        decimal[] price = { 6.99M, 8.99M, 12.50M, 15.00M};

        Console.WriteLine("Please enter a pizza size : ");
        string pizzaSize = Console.ReadLine();

        bool isValid = false;

        while(isValid == false){
              for (int i = 0; i < size.Length; i  )
              {
                    if (size[i] == pizzaSize)
                    {
                          Console.WriteLine("Your pizza size is "   pizzaSize   ". The price is "   price[i].ToString("C"));
                          isValid = true;
                          break;
                     }
              }
        
              if (isValid == false){
                    Console.WriteLine("Please enter a valid pizza size");
                    pizzaSize = Console.ReadLine();
              }
        }

        Console.ReadKey();
    }
 

Ответ №2:

Блок else будет выполняться каждый раз, когда проверяемое условие является ложным, что было бы по крайней мере 3 раза, даже если условие было истинным, то есть, если у вас не было return инструкции, которая не позволит циклу продолжаться, как только код попадет else , он немедленно вернется из программы.

Данный ответ уже решает эти проблемы, я бы изменил сравнение, вы бы хотели, чтобы ваш код распознавал нижний и верхний регистр для ввода, использование Equals было бы более надежным подходом:

 static void Main(string[] args)
{
    string[] size = { "S", "M", "L", "X" };
    decimal[] price = { 6.99M, 8.99M, 12.50M, 15.00M };

    Console.Write("Please enter a pizza size : ");
    string pizzaSize;
    var exists = false;

    while (!exists amp;amp; (pizzaSize = Console.ReadLine()) != null)
    {
        for (int i = 0; i < size.Length; i  )
        {
            if (size[i].Equals(pizzaSize, StringComparison.OrdinalIgnoreCase))
            {
                Console.WriteLine("Your pizza size is "   size[i]   ". The price is "   price[i].ToString("C"));
                exists = true;
                break;
            }
        }
        if (!exists)
        {
            Console.Write("Please enter a valid pizza size: ");
        }
    }
    Console.ReadKey();
}
 

И несколько незначительных настроек, чтобы сделать ваш ввод-вывод более удобным для пользователя.

Ответ №3:

Похоже, что вы возвращаетесь в свою другую ветвь при первом несоответствии и, следовательно, покидаете всю функцию.

Существует несколько способов исправить ваш код. Не слишком прикасаясь к своему коду, вы могли бы ввести оператор break после строки записи в ветке if, чтобы выйти из цикла (вы уже закончили, не нужно сверяться с другими размерами) и добавить дополнительный оператор if внутри ветки else, обернув его содержимое, чтобы проверить, является ли текущая итерация цикла последней. Если это последняя итерация и она все еще не сопоставлена, это может быть только недопустимый размер.

Но на самом деле вам было бы лучше использовать простой переключатель, а не повторять вручную.