我学习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行
答案 0 :(得分:3)
如评论中所述,您正在运行str.split()
,然后仅使用索引0
和索引1
访问它的输出。在请求索引0
或1
时,如果索引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的问题,因为您没有抓住overflowexception或formatexception。
Convert.ToInt32()
如@ckuri和What'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