Console.ReadLine将48添加到int

当我向ReadLine()输入0时,我得到48。

这是一个错误吗?

class Program { static void Main(string[] args) { string name; int age; readPerson(out name, out age); } static void readPerson(out string name, out int age) { Console.Write("Enter name: "); name = Console.ReadLine(); Console.Write("Enter age: "); age = Console.Read(); Console.WriteLine("Name: {0}; Age: {1}", name, age.ToString()); } } 

根据MSDN文档, Console.Read方法返回:

输入流中的下一个字符,如果当前没有更多字符要读取,则为负一(-1)。

所以,你真正看到的只是当前流上的第一个字符(即在最后两个Enter推送之间收到的字符)。

在你的unit testing过程中,似乎值被移动了48,因为从“0”到“9”的字符的ASCII值是,你猜对了,48为’0’,49为” 1’等:

ASCII表

由于您未指定转换,因此将流内容“自动”读取为char值,并且对Read()调用显示其ASCII十进制等值。

您可以使用以下简单测试validation这一点:

 static void TestRead() { int current = 0; Console.Write("Enter 1: "); current = Console.Read(); Console.WriteLine("Next char: {0}", current); current = Console.Read(); Console.WriteLine("Next char: {0}", current); current = Console.Read(); Console.WriteLine("Next char: {0}", current); Console.Write("Enter 22: "); current = Console.Read(); Console.WriteLine("Next char: {0}", current); current = Console.Read(); Console.WriteLine("Next char: {0}", current); current = Console.Read(); Console.WriteLine("Next char: {0}", current); current = Console.Read(); Console.WriteLine("Next char: {0}", current); } 

这将导致:

产量

您会注意到对Read()的背靠背调用从流中获取单个字符,并为您提供其ASCII十进制等效值。 另外,请注意Windows如何为Enter键的每个笔划附加回车符(ASCII 13)和换行符(ASCII 10),您的程序会忠实地回复给您。

稍微修改一下这个测试方法有助于推动缺乏特定方向的点,运行时会将输入流的内容解释为字符:

 static void TestReadModified() { int current = 0; Console.Write("Enter a: "); current = Console.Read(); Console.WriteLine("Next char: {0}", current); current = Console.Read(); Console.WriteLine("Next char: {0}", current); current = Console.Read(); Console.WriteLine("Next char: {0}", current); } 

正如所料,上面的方法将返回字符’a’的ASCII值:

输出一封信

正如其他人已经提到的那样,这很容易解决。 只需通知运行时您希望将值解释为int 。 至少,检查收到的输入是一个数字可能也是一个好主意:

 static void readPerson(out string name, out int age) { Console.Write("Enter name: "); name = Console.ReadLine(); Console.Write("Enter age: "); // in this case, we could simply use tempAge (defaults to 0) // but it's just practice to check TryParse's success flag int tempAge; var success = Int32.TryParse(Console.ReadLine(), out tempAge); age = success ? tempAge : 0; Console.WriteLine("Name: {0}; Age: {1}", name, age); Console.ReadLine(); } 

不,这根本不是一个bug。

Console.Read()返回输入的任何字符的ASCII字符代码。 数字0的ASCII码为48,数字1的ASCII码为49,依此类推。 它没有任意添加数字48,也没有与out参数有任何关系。

您需要读取一行并相应地将输入转换为整数:

 Console.Write("Enter age: "); age = Convert.ToInt32(Console.ReadLine()); 

如果您因任何原因需要使用Read() ,那么就像我在评论中所说的那样,您需要将结果转换为char 。 您还需要将变量从int age更改为char age

 class Program { static void Main(string[] args) { string name; char age; readPerson(out name, out age); } static void readPerson(out string name, out char age) { Console.Write("Enter name: "); name = Console.ReadLine(); Console.Write("Enter age: "); age = (char) Console.Read(); Console.WriteLine("Name: {0}; Age: {1}", name, age.ToString()); } } 

请记住, Read()一次只能读取一个字符,所以如果你需要解析一个以上数字的年龄,这将不起作用,而你只需使用ReadLine()就可以了。

正在打印数字的ASCII代码。 请注意, Console.Read()从标准输入中读取下一个字符并返回一个int。 因此,当您输入字符 0(不是整数0)时,它将返回ASCII码48,依此类推。 此外,此ASCII代码是字符的整数代码(例如0),因此转换为此代码的int是多余的。 你在age中读取字符串并将其转换为整数,这可以使用Console.ReadLine完成,然后使用int.TryParse等。