C# 使用String.ToUpper()时程序退出;在包含空格的字符串上

C# 使用String.ToUpper()时程序退出;在包含空格的字符串上,c#,command-line,.net-core-3.1,C#,Command Line,.net Core 3.1,让我先说我是C#的新手 我目前正在开发我的第一个命令行应用程序,它在当前状态下可以做两件事。其中一个是计算器,我需要更多的学习才能让它真正工作,另一个是字符串大写 我有一个字符串nameCapInput=Console.Readline(),它接收用户输入,然后对其进行分析以确保不允许使用数字: using System; using System.Linq; namespace First_Console_Project { class Program { s

让我先说我是C#的新手

我目前正在开发我的第一个命令行应用程序,它在当前状态下可以做两件事。其中一个是计算器,我需要更多的学习才能让它真正工作,另一个是字符串大写

我有一个
字符串nameCapInput=Console.Readline()
,它接收用户输入,然后对其进行分析以确保不允许使用数字:

using System;
using System.Linq;

namespace First_Console_Project
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("My first ever console application - 2020/2/26\n\n\n");
        programSel:
            Console.WriteLine("What do you want to do?\n");
            Console.WriteLine("1. Calculate Numbers \n2. Capitalize Letters/Strings");
            Console.WriteLine("Input your desired action:");
            var inputVar = Console.ReadLine();
            switch (inputVar)
            {
                case "1":
                    //Calculator code goes here
                    Console.WriteLine("Number 1 succeeded, opening calculator... Stand by");
                    Console.WriteLine("Calulator Loaded.");
                    Console.WriteLine("Doesn't work right now. Type \"exit\" to get back to the \"what do you want to do\" page.");
                    //Code goes here when I have learned the proper methods
                calcInput:
                    var calcInput = Console.ReadLine();
                    if (calcInput == "exit")
                    {
                        goto programSel;
                    } else
                    {
                        Console.WriteLine("Unknown command. Type \"exit\" to get back to the \"what do you want to do\" page.");
                        goto calcInput;
                    }
                case "2":
                    Console.WriteLine("Loading string capitalizer...");
                    Console.WriteLine("Type any string made of letters only without spaces, because if you use spaces, the program will exit. The output will make them all uppercase. Type \"exit\" to get back to the \"what do you want to do\" page.");
                inputCap:
                    string nameCapInput = Console.ReadLine();
                    bool containsInt = nameCapInput.Any(char.IsDigit);
                    bool isMadeOfLettersOnly = nameCapInput.All(char.IsLetter);
                    if (nameCapInput == "exit")
                    {
                        goto programSel;
                    }
                    else if (containsInt)
                    {
                        Console.WriteLine("You can't capitalize numbers. Use letters only. Try again.");
                        goto inputCap;
                    }
                    else if (isMadeOfLettersOnly)
                    {
                        string upper = nameCapInput.ToUpper();
                        Console.WriteLine($"The uppercase version of your entered text is: {upper}");
                        goto inputCap;
                    }
                    break;
                    }
            }
        }
}
现在,一切都很好,它将我放入其中的所有内容进行了capialize,除了带有空格的字符串。当我键入一个包含空格的字符串时,程序将以代码0退出。我还不是很擅长C#,所以我真的不知道从这里该去哪里。感谢您的帮助

每次我在C#中学到一些新东西时,我都会尝试将其应用到我的项目中,这样我就可以真正学习如何实施它,从而知道何时以及如何使用我所学的东西。这就是一个例子

编辑:添加了代码的其余部分。 非常感谢大家。我在这里学到了两件事:

  • goto
    是个坏习惯
  • 我绝对需要开始学习调试自己的代码
  • 检查文档:

    根据
    isleter
    函数的文档,返回true的情况中不包括空格

    我建议您对此使用正则表达式,或者将上一个案例改为

    else if (!containsInt)
    {
        var upper = nameCapInput.ToUpper();
        Console.WriteLine($"The uppercase version of your entered text is: {upper}");
        goto inputCap;
    }
    
    还要检查goto的文档:

    goto语句将程序控件直接传输到带标签的语句

    goto的一个常见用法是将控制权转移到特定的switch case标签或switch语句中的默认标签

    goto语句对于摆脱深度嵌套的循环也很有用


    在任何情况下,您都不能使用它。

    问题的关键在于您只检查输入是否包含字母(而不是空格)。一个简单的解决方法是稍微改变一下你的LINQ

    bool isMadeOfLettersOnly = nameCapInput.All(c => char.IsLetter(c) || char.IsWhiteSpace(c));
    
    因此,现在输入字母或空格将被视为有效

    此外,使用
    goto
    是一个非常糟糕的主意。通常,不应该有任何理由使用
    goto

    要解决此问题,请使用while循环和方法:

    public static void Main()
    {
        bool exit = false;
        do {
            exit = ProcessInput();
        }
        while(!exit);
    }
    
    private static bool ProcessInput()
    {
        string nameCapInput = Console.ReadLine();
    
        bool containsInt = nameCapInput.Any(char.IsDigit);
        bool isMadeOfLettersOnly = nameCapInput.All(c => char.IsLetter(c) || char.IsWhiteSpace(c));
    
        if (nameCapInput.Equals("exit", StringComparison.CurrentCultureIgnoreCase))
        {
            return true; //exiting so return true
        }
        else if (containsInt)
        {
            Console.WriteLine("You can't capitalize numbers. Use letters only. Try again.");
        }
        else if (isMadeOfLettersOnly)
        {
            string upper = nameCapInput.ToUpper();
            Console.WriteLine("The uppercase version of your entered text is: {0}", upper);
        }   
        return false; //no exit, so return false
    }
    
    这只是一个快速的重构,您可以让它变得更好


    首先,完全停止使用
    goto
    。现在不是20世纪80年代。使用
    goto
    是你需要马上摆脱的习惯。当你有一个空格时,isMadeOfLettersOnly将是错误的。你没有显示完整的程序,所以我们不知道如果执行从显示的结尾掉下来会发生什么。它需要重复,去掉
    goto
    哇,你很多人都说
    goto
    不好。那我该用什么呢?谢谢。我唯一没有得到的是
    while(!exit)。我没有看到
    被用作一种方法。这有什么用?看起来它只有在退出不正确时才会执行某些操作
    !退出
    @TimmSkiller这是一个
    do/while
    循环,读入它。本质上意味着在检查条件之前,
    do
    块将至少执行一次(
    while()
    )。因此,在您的情况下,它将要求用户输入,如果输入是
    “exit”
    ,它将返回一个true。由于我们将
    ProcessInput()
    的返回值赋值给变量
    exit
    ,它将触发循环结束,因为变量不再为false。这是有意义的。再次感谢。