C# C语言中用户是/否控制台输入的解析和循环#
我正在编写一个方法,我将在另一个代码中使用它,所以我首先单独编写它 代码根据输入的第一个字符返回布尔值(是,是,y,是,否,…)。但当输入与Y或N不同时,它就会开始起作用。在eg3中,它一直保持在循环中,直到Console.Read遇到Y或N或没有字符为止。在最后一种情况下,它将再次请求输入 我使用的是控制台。读错了还是代码中有其他错误? 提前谢谢 编辑:最终,这个解决方案是有效的吗 eg1: 基于@StuartLC答案的替代解决方案:C# C语言中用户是/否控制台输入的解析和循环#,c#,C#,我正在编写一个方法,我将在另一个代码中使用它,所以我首先单独编写它 代码根据输入的第一个字符返回布尔值(是,是,y,是,否,…)。但当输入与Y或N不同时,它就会开始起作用。在eg3中,它一直保持在循环中,直到Console.Read遇到Y或N或没有字符为止。在最后一种情况下,它将再次请求输入 我使用的是控制台。读错了还是代码中有其他错误? 提前谢谢 编辑:最终,这个解决方案是有效的吗 eg1: 基于@StuartLC答案的替代解决方案: bool ans = true, loop = true;
bool ans = true, loop = true;
do
{
switch (Console.ReadLine().ToUpper().FirstOrDefault())
{
case 'Y':
ans = true;
loop = false;
break;
case 'N':
ans = false;
loop = false;
break;
default:
Console.WriteLine("You can only answer with Yes or No");
break;
}
} while (loop==true);
Console.WriteLine(ans);
根据@Lasse的注释-如果用户键入多个字符,您将循环用户键入的字符串中的每个字符,从而为用户键入的每个字符打印一行新的输出。相反,使用
ReadLine
将把输入解析为单个字符串,然后Linq扩展FirstOrDefault()
将安全地获取字符串中的第一个char
:
YN = char.ToUpper(Console.ReadLine().FirstOrDefault());
另一方面,C#也支持一种更符合您需求的语法,即循环中至少有一次迭代,并在循环结束时进行检查,而不是使用强制的false
条件启动while
循环:
do
{
Console.WriteLine("Yes or No?");
YN = char.ToUpper(Console.ReadLine().FirstOrDefault());
switch (YN)
{
case 'Y':
ans = true;
break;
case 'N':
ans = false;
break;
default:
Console.WriteLine("You can only answer with Yes or No");
YN = 'x';
break;
}
}
while (YN == 'x');
再操作的后续问题
我现在可以完全删除“YN”并在开始时放置一个开关(Console.ReadLine().FirstOrDefault().ToUpper())
,在结束时放置一个开关(ans==true | | ans==false)
不完全正确-因为ans
是一个布尔值,它只能有两个状态(true或false),并且您需要对至少3个状态(true、false和invalid)进行建模。尽管您可以使用一个可为空的布尔值(bool?
)来模拟这3种状态(其中null=invalid),但我个人不喜欢使用null
来表示未知的东西,因为这总是导致NullReferenceException
深渊,而C#还没有(尚未)选择“Option”类型/Monad(就像Java的可选的)
如果你对C#8模式匹配和元组没问题,你可以通过拆分“输入是否有效”和“有效输入值是多少”这两个关注点,使代码更加简洁,并进行如下重构。你还可以将switch表达式重构为它自己的方法,从解析逻辑中拆分“UI”的关注点,这总是个好主意
static void Main(string[] args)
{
bool ans;
bool isValid;
do
{
Console.WriteLine("Yes or No?");
(ans, isValid) = ParseInput(Console.ReadLine());
if (!isValid)
{
Console.WriteLine("You can only answer with Yes or No");
}
}
while (!isValid);
Console.WriteLine(ans);
(bool ans, bool isValid) ParseInput(string input) =>
char.ToUpper(input.FirstOrDefault()) switch
{
'Y' => (true, true),
'N' => (false, true),
_ => (default, false)
};
}
您使用的是Console.Read
,它将一次读取1个字符。如果您想比较完整的输入,请使用Console.ReadLine
,并将其作为字符串读取,然后在必要时切掉第一个字符进行比较。如果您打印YN的失败值以及错误消息,您将看到(用于输入)“我不知道”)在它找到“N”之前,你得到了值“I”、“D”、“O”@Jonathan我已经更新了答案来解决这个问题。顺便说一句——我错了——因为一些空洞的原因,char.ToUpper
。你是对的。
bool ans = true, loop = true;
do
{
switch (Console.ReadLine().ToUpper().FirstOrDefault())
{
case 'Y':
ans = true;
loop = false;
break;
case 'N':
ans = false;
loop = false;
break;
default:
Console.WriteLine("You can only answer with Yes or No");
break;
}
} while (loop==true);
Console.WriteLine(ans);
YN = char.ToUpper(Console.ReadLine().FirstOrDefault());
do
{
Console.WriteLine("Yes or No?");
YN = char.ToUpper(Console.ReadLine().FirstOrDefault());
switch (YN)
{
case 'Y':
ans = true;
break;
case 'N':
ans = false;
break;
default:
Console.WriteLine("You can only answer with Yes or No");
YN = 'x';
break;
}
}
while (YN == 'x');
static void Main(string[] args)
{
bool ans;
bool isValid;
do
{
Console.WriteLine("Yes or No?");
(ans, isValid) = ParseInput(Console.ReadLine());
if (!isValid)
{
Console.WriteLine("You can only answer with Yes or No");
}
}
while (!isValid);
Console.WriteLine(ans);
(bool ans, bool isValid) ParseInput(string input) =>
char.ToUpper(input.FirstOrDefault()) switch
{
'Y' => (true, true),
'N' => (false, true),
_ => (default, false)
};
}