C#不允许我将某些变量放在方法的开头。我不明白为什么不

时间:2018-11-04 10:46:04

标签: c#

我学习C#已有一个多月了。我正在做一个练习,要求用户以24小时制输入时间,并检查时间是否有效。

但这并不重要。我的问题是我对错误感到困惑。下面的代码创建了一个未处理的异常,并说我的输入字符串格式不正确。它指定了第22行。(小时变量。)

现在,我已经通过将所有除userInput之外的变量移动到try块中来解决此问题。但是我很困惑为什么要修复它。我很新,并且尝试过使用Google搜索,但是说实话,我什至不知道该如何表达我的问题。

完整的(固定的)代码如下。感谢大家的耐心配合。

{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Please enter a time value in the 24-hour time format. (ex. 19:00)");
            var userInput = Console.ReadLine();
            var userComponents = userInput.Split(':');
            var hour = Convert.ToInt32(userComponents[0]);
            var minute = Convert.ToInt32(userComponents[1]);    

            if (String.IsNullOrWhiteSpace(userInput))
            {
                Console.WriteLine("Invalid Time");
                return;
            }

            try
            {                      
                if (hour <= 23 && hour >= 00 && minute >= 0 && minute <= 59)
                    Console.WriteLine("Ok");
                else
                    Console.WriteLine("Invalid Time");
            }

            catch(Exception)
            {
                Console.WriteLine("Invalid Time");
            }
       }
    }
}

有人要求我发布固定代码:

{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Please enter a time value in the 24-hour time format. (ex. 19:00)");
            var userInput = Console.ReadLine();  

            if (String.IsNullOrWhiteSpace(userInput))
            {
                Console.WriteLine("Invalid Time");
                return;
            }

            try
            {
                var userComponents = userInput.Split(':');
                var hour = Convert.ToInt32(userComponents[0]);
                var minute = Convert.ToInt32(userComponents[1]);

                if (hour <= 23 && hour >= 00 && minute >= 0 && minute <= 59)
                    Console.WriteLine("Ok");
                else
                    Console.WriteLine("Invalid Time");
            }

            catch(Exception)
            {
                Console.WriteLine("Invalid Time");
            }
       }
    }
}

有人还请求了调试器信息:

  

System.IndexOutOfRangeException HResult = 0x80131508消息=索引   在数组的边界之外。来源=第6节24小时制
  StackTrace:在Section_6_24_Hour_Time.Program.Main(String [] args)   在D:\ Repos \ Mosh C#Udemy \ Exercises \ C#基本练习\第6节   24小时制\第6节24小时制\ Program.cs:第23行

4 个答案:

答案 0 :(得分:3)

如评论中所述,您正在运行str.split(),然后仅使用索引0和索引1访问它的输出。在请求索引01时,如果索引class Program { static void Main(string[] args) { Console.WriteLine("Please enter a time value in the 24-hour time format. (ex. 19:00)"); var userInput = Console.ReadLine(); if(string.IsNullOrEmpty(userInput)) { Console.WriteLine("No input"); return; } if(!userInput.Contains(':')) { Console.WriteLine("Input does not have `:` in it. Invalid Time."); return; } var userComponents = userInput.Split(':'); if(userComponents.Length != 2) { Console.WriteLine("Invalid Time"); return; } if(string.IsNullOrEmpty(userComponents[0]) || string.IsNullOrEmpty(userComponents[1]) { Console.WriteLine("No hours or minutes given. Invalid Time"); return; } try { var hour = Convert.ToInt32(userComponents[0]); var minute = Convert.ToInt32(userComponents[1]); } catch(OverFlowException e) { // Do something with this. return; } catch (FormatException e) { // Do something with this. return; } if (hour <= 23 && hour >= 00 && minute >= 0 && minute <= 59) Console.WriteLine("Ok"); else Console.WriteLine("Invalid Time"); } } Convert.ToInt32不存在,则会出现索引超出范围异常,告诉您索引0或1上的项目不存在。

然后是Convert.ToInt32的问题,因为您没有抓住overflowexceptionformatexception

Convert.ToInt32()

编辑

@ckuriWhat's the main difference between int.Parse() and Convert.ToInt32所述,由于我们在这里处理用户输入,因此人们应该更喜欢int.TryParse()而不是ArgumentNullException

  
      
  • 如果您有字符串,并且希望它始终是整数(例如,如果某些Web服务将字符串格式的整数交给您),则可以使用Int32.Parse()

  •   
  • 如果您要收集用户的输入,通常应使用Int32.TryParse(),因为当用户输入无效输入时,它可以对情况进行更细粒度的控制。

  •   
  • Convert.ToInt32()将对象作为其参数。 (有关其工作原理,请参见Chris S的答案)

  •   
     当

Int32.Parse()的自变量为null时,也不会像Convert.ToInt32()那样抛出Int32.Parse()。这也意味着error(msg, (Object[]) expected); 可能比if (userComponents.Length < 2) { Console.WriteLine("Invalid Time"); return; } var hour = Convert.ToInt32(userComponents[0]); var minute = Convert.ToInt32(userComponents[1]); 慢一点,尽管实际上,除非您在循环中进行大量迭代,否则您永远不会注意到它。

答案 1 :(得分:2)

在访问数组的元素之前,请检查其是否具有所需的长度:

userComponents[1]

请注意,输入字符串可能不包含冒号,因此ast.literal_eval将返回仅包含一个元素的数组。在这种情况下,from ast import literal_eval from io import StringIO # replicate csv file x = StringIO("""A,B ,"('t1', 't2')" "('t3', 't4')",""") def literal_converter(val): # replace first val with '' or some other null identifier if required return val if val == '' else literal_eval(val) df = pd.read_csv(x, delimiter=',', converters=dict.fromkeys('AB', literal_converter)) print(df) A B 0 (t1, t2) 1 (t3, t4) 不存在,因此是例外。

答案 2 :(得分:0)

此错误表明您正在尝试将不可转换的字符串值转换为int(在这种情况下)。因此,您应该确保分割后输入的值可转换为int,并且在转换前对它们进行Trim()也很不错:

 var hour = Convert.ToInt32(userComponents[0].Trim());
 var minute = Convert.ToInt32(userComponents[1].Trim()); 

答案 3 :(得分:-1)

在尝试拆分userInput之前,应首先检查IsNullOrWhiteSpace