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;
};