Y/N или Y/N в цикле

Привет, ребята, просто возникли проблемы с реализацией Y/N или Y/N в цикле. Я разработал его таким образом, чтобы пользователь мог использовать как заглавные, так и маленькие буквы Y и N для своего ответа в цикле. кстати вот мой код, но не могу заставить его работать:

do
        {
            Console.WriteLine("\nSelect additional topping/s\n");

            Console.WriteLine("1 - Extra meat: 200");
            Console.WriteLine("2 - Extra cheese: 100");
            Console.WriteLine("3 - Extra veggies: 80\n");

            int selectedTopping = Convert.ToInt32(Console.ReadLine());

            switch (selectedTopping)
            {
                case 1:
                    pizza = new MeatToppings(pizza);
                    break;

                case 2:
                    pizza = new CheeseToppings(pizza);
                    break;

                case 3:
                    pizza = new VeggieToppings(pizza);
                    break;

                default:
                    break;
            }

            Console.WriteLine("\nAdd more toppings? Y/N");


        }

        while ((Console.ReadLine() == "Y") || (Console.ReadLine() == "y"));

6 ответов

while ((Console.ReadLine() == "Y") || (Console.ReadLine() == "y"));

Это будет читать 2 разные строки, так как вы звоните ReadLine() дважды. Вам нужно вызвать его один раз и сохранить значение.

Попробуй использовать String.Equals а также StringComparison:

String.Equals(Console.ReadLine(), "y", StringComparison.CurrentCultureIgnoreCase);

из MSDN:

CurrentCultureIgnoreCase: Сравнение строк с использованием правил сортировки с учетом культуры, текущей культуры и игнорирование случая сравниваемых строк.

OrdinalIgnoreCase: Сравните строки, используя порядковые правила сортировки и игнорируя регистр сравниваемых строк.

Ты можешь использовать ToUpper

while ((Console.ReadLine().ToUpper() == "Y") );

Проверять Y или же y игнорируя регистр, вы должны использовать перегрузку string.Equals(string,StringComparison).

while (Console.ReadLine().Equals("Y", StringComparison.InvariantCultureIgnoreCase));

Пожалуйста, ознакомьтесь с турецкой проблемой и почему вы должны заботиться перед использованием ToUpper или же ToLower для сравнения строк с игнорированием регистра.

Ваш текущий код читает строки из консоли дважды, поэтому ваш код удерживает 2-е значение.

Как только что указал Остин, вы используете ReadLine дважды в операторе while.

Стоит упомянуть одну вещь - попытаться следовать правилу модульности, это поможет ускорить реализацию и отладку нашего кода.

Прошло много времени с тех пор, как я занимался программированием на C#, поэтому sudo-кодирование это в стиле Java

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

public class TerminalUtil {
    private TerminalUtil() {}

    public static boolean isYes(String msg){ return (msg.ToUpper() == "Y" || msg.ToUpper() == "YES"); }
    public static boolean isNo(String msg){ return (msg.ToUpper() == "N" || msg.ToUpper() == "NO"); }
   // You also might want basic conditionals to check if string is numeric or contains letters.

    // I like using recursion for command line utilities so having a method that can re-print messages is handy
    public static void display(String[] messages){
        for(String msg : messages){
            Console.WriteLine(msg);
        }
    }

    public static boolean enterYesOrNo(String[] messages, String[] errorMessages){
        display(messages)
        String input = Console.ReadLine();
        if( isYes(input) ){
            return true;
        } else if( isNo(input) ){ 
            return false; 
        } else {
             display(errorMessages); // Maybe something like, you didn't enter a yes or no value.
             enterYesOrNo(messages, errorMessages); // Recursive loop to try again.
        }

    }
}

Вот как может выглядеть код заказа пиццы

public class OrderPizza{
    public static int selectToppings(){
        String[] message = new String[4];
        message[0] = ("\nSelect additional topping/s\n");
        message[1] = ("1 - Extra meat: 200");
        message[2] = ("2 - Extra cheese: 100");
        message[3] = ("3 - Extra veggies: 80\n");

       int option =  TerminalUtils.entryNumeric(message, {"You entered an non-numeric character, try again"} );
       if( option > 0 && option <= 3 ){
           return option;
       } else {
          Console.WriteLine("Number must be between 1 - 3, try again.");
          return selectToppings();
       }
    }

    public static Pizza order(){
        Pizza pizza = new Pizza();

        while(true){
            int toppingCode = selectTopping();
            pizza.addTopping(toppingCode);
            if(!TerminalUtil.enterYesOrNo({"\nAdd more toppings? Y/N"}, {"Please enter a 'Y'es or 'N'o"}) ){
                break;
            }
        }
    }
}

Основным преимуществом этого является то, что бизнес-логика цикла while была сокращена, и вы можете повторно использовать код в TerminalUtils. Кроме того, это ни в коем случае не элегантное решение, я ленивый, и это 3 часа IRL, но этого должно быть достаточно, чтобы мяч катился.

Одна вещь, которую вы, вероятно, должны пересмотреть, это использовать целочисленные коды для представления начинки. Использование enum может облегчить реализацию.

Я также заметил, что вы добавляете три разных типа пиццы, которые я предполагаю три отдельных объекта.

Поскольку вы зацикливаетесь на добавлении начинки к пицце, создайте абстрактный класс пиццы. Таким образом, вы можете расширить обычные готовые пиццы, такие как пепперони или сыр, и использовать класс абстрактной пиццы, если хотите, чтобы клиент настраивал свой заказ.

Я не нашел лучшего способа, чем:

while ( str!="N" )
{
    str = Console.ReadLine();
    str = str.ToUpper();
    if (str == "Y");
       break;
};
Другие вопросы по тегам