C# C语言中用户是/否控制台输入的解析和循环#

C# C语言中用户是/否控制台输入的解析和循环#,c#,C#,我正在编写一个方法,我将在另一个代码中使用它,所以我首先单独编写它 代码根据输入的第一个字符返回布尔值(是,是,y,是,否,…)。但当输入与Y或N不同时,它就会开始起作用。在eg3中,它一直保持在循环中,直到Console.Read遇到Y或N或没有字符为止。在最后一种情况下,它将再次请求输入 我使用的是控制台。读错了还是代码中有其他错误? 提前谢谢 编辑:最终,这个解决方案是有效的吗 eg1: 基于@StuartLC答案的替代解决方案: bool ans = true, loop = true;

我正在编写一个方法,我将在另一个代码中使用它,所以我首先单独编写它

代码根据输入的第一个字符返回布尔值(是,是,y,是,否,…)。但当输入与Y或N不同时,它就会开始起作用。在eg3中,它一直保持在循环中,直到Console.Read遇到Y或N或没有字符为止。在最后一种情况下,它将再次请求输入

我使用的是控制台。读错了还是代码中有其他错误? 提前谢谢

编辑:最终,这个解决方案是有效的吗

eg1:

基于@StuartLC答案的替代解决方案:

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