Console.ReadLine将48添加到int

时间:2012-02-06 06:28:24

标签: c# out

当我输入0到ReadLine()时,我得到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());
    }
}

3 个答案:

答案 0 :(得分:9)

不,这根本不是一个错误。

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()

答案 1 :(得分:7)

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

  

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

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

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

ASCII Table

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

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

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

这将导致:

Output

你会注意到Read()的背靠背调用从流中获取单个字符,并给你ASCII等效的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值:

Output for a letter

正如其他人已经提到的,这很容易解决。只需通知运行时您希望将值解释为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();
}

答案 2 :(得分:1)

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