【问题标题】:Console.ReadLine add 48 to intConsole.ReadLine 将 48 添加到 int
【发布时间】:2012-02-27 16:57:39
【问题描述】:

当我将 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());
    }
}

【问题讨论】:

标签: c# out


【解决方案1】:

不,这根本不是错误。

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() 一次只能读取一个字符,因此如果您需要解析一个多于一位的年龄,这将不起作用,您最好使用 @987654330 @ 代替。

【讨论】:

  • 谢谢。有效。只是好奇:如果我使用 Read 而不是 ReadLine,该语句再次返回 ASCII 字符。为什么?
  • 它总是返回输入流中下一个字符的 ASCII 字符代码。没有“为什么”。
  • 这不是我要问的“为什么”。 'Convert.ToInt32(Console.ReadLine())' 有效,但 'Convert.ToInt32(Console.Read())' 仍然返回 ASCII。
  • @KMC:我说它返回 ASCII 字符代码。将其转换为整数不会改变它,因为它已经是一个整数。但是,如果您尝试将其转换为字符,它应该会返回字符本身。
  • 如果我使用 Read 而不是 Readline,如何将 ASCII 转换为 int?
【解决方案2】:

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

【讨论】:

  • @KMC - 您的编辑似乎表明您没有阅读我的答案。当您键入时,读取获取字符 0,而不是整数 0。所以它返回 48,这是它的 ascii 代码。请注意,这 48 本身是一个整数,因此将 48 转换为 int 将仅返回 48。您没有将字符 0 转换为 int,而是将 48 转换为 int。
  • 我认为 ASCII 在 Utf16 中有 Char 类型?不应该将 char 转换为 int 应该隐式地将 char 代码转换为其对应的 int?
  • @KMC: Console.Read() 不返回字符。
【解决方案3】:

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

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

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

在您的单元测试期间,这些值似乎被移动了 48,因为碰巧从 '0' 到 '9' 的字符的 ASCII 值是,你猜对了,48 代表 '0', 49 代表“1”等:

由于您没有指定转换,因此流内容“自动”读取为 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);
}

这将导致:

您会注意到对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();
}

【讨论】:

猜你喜欢
  • 2022-11-16
  • 2021-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-16
  • 2013-05-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多