Console.Read()和Console.ReadLine()的问题

6

我一直在尝试在C#中使用Console.Read()和Console.ReadLine(),但是得到了奇怪的结果。例如这段代码:

Console.WriteLine("How many students would you like to enter?");
int amount = Console.Read();
Console.WriteLine("{0} {1}", "amount equals", amount);

for (int i=0; i < amount; i++)
{
     Console.WriteLine("Input the name of a student");
     String StudentName = Console.ReadLine();
     Console.WriteLine("the Students name is " + StudentName);
}

在我输入1作为学生数量时,这个程序给出了49的结果,甚至没有让我输入学生姓名。

8
请在ASCII表中查找49 :) http://www.asciitable.com/ - asawyer
10个回答

11

这是因为您读取了一个字符。使用适当的方法,如ReadInt32(),该方法会负责将读取的符号正确转换为所需类型。

之所以得到49,是因为它是'1' 符号的字符编码,而 不是 它的整数表示。

char     code
0 :      48
1 :      49
2:       50
...
9:       57
例如:ReadInt32() 可以像这样:
public static int ReadInt32(string value){
      int val = -1;
      if(!int.TryParse(value, out val))
          return -1;
      return val;
}

并像这样使用:

int val = ReadInt32(Console.ReadLine());

能够创建扩展方法将非常好,但不幸的是,在静态类型上无法创建扩展方法,Console 是一个 static 类型。


int.TryParse 很简单,而且你的 ReadInt32 方法中的元素在调用方法中被重复使用,因此最好使用 Rune FS 或 Steve 提出的解决方案。 - Trisped
1
@Trisped:如果在程序流程中需要多次从控制台读取“整数”,我更喜欢将其放在单个方法中,并调用方法,而不是到处写意大利面条式代码。 - Tigran
如果您使用您的方法编写整个代码块,您会发现您使用的变量和方法调用数量与仅使用int.TryParse方法相同(因为您必须验证输入)。 如果除了将字符串转换为整数之外还有更多内容,那么我会同意,因为将代码放在一个方法中比分散在所有使用它的地方更容易/更安全。 - Trisped

3

对于可能仍需要此信息的人:

static void Main(string[] args)
{
     Console.WriteLine("How many students would you like to enter?");
     var amount = Convert.ToInt32(Console.ReadLine());

     Console.WriteLine("{0} {1}", "amount equals", amount);

     for (int i = 0; i < amt; i++)
     {
         Console.WriteLine("Input the name of a student");
         String StudentName = Console.ReadLine();
         Console.WriteLine("the Students name is " + StudentName);
     }
}

3

尝试以这种方式更改您的代码

int amount;
while(true)
{
    Console.WriteLine("How many students would you like to enter?"); 
    string number = Console.ReadLine(); 
    if(Int32.TryParse(number, out amount))
        break;
}
Console.WriteLine("{0} {1}", "amount equals", amount); 
for (int i=0; i < amount; i++) 
{ 
    Console.WriteLine("Input the name of a student"); 
    String StudentName = Console.ReadLine(); 
    Console.WriteLine("the Students name is " + StudentName); 
} 

使用ReadLine而不是Read,然后使用Int32.TryParse检查用户输入是否为整数。如果用户没有输入有效数字,则重复提问。
使用Console.Read将限制您的输入为单个字符,需要进行转换并检查是否为有效数字。

当然,这只是一个简单的示例,没有任何错误检查或任何类型的安全中止循环。


如果他想让用户只能输入一个字符,而不是整行输入呢? - Servy
但这将限制学生人数为9人。而且我从未听说过这个要求。 - Steve
他似乎费尽心思避免使用ReadLine,这表明他只想要一个数字。 - Servy
@Trisped 嗯,很明显他不知道Read的工作原理。更多的问题是,“他对Read的哪些方面存在误解?” - Servy

2

如果您从读取中得到一个字符 char 而不是整数,则需要先将其转换为字符串,然后再将该字符串解析为整数。实现可能如下所示:

    Console.WriteLine("How many students would you like to enter?");
    var read = Console.ReadLine();
    int amount;
    if(int.TryParse(read,out amount)) {
      Console.WriteLine("{0} {1}", "amount equals", amount);

      for (int i=0; i < amount; i++)
      {
        Console.WriteLine("Input the name of a student");
        String StudentName = Console.ReadLine();
        Console.WriteLine("the Students name is " + StudentName);
      }
    }

我已经改用readline,因为它返回字符串并不会随意限制学生人数为9人(一个数字的最大值)


谢谢大家的帮助,程序现在似乎运行正常。 - Mike Cornell

0

简而言之:在Windows中,Enter键不是单个字符。这个事实是许多与Console.Read()方法相关的问题的根源。

完整细节:如果您在计算机上运行以下代码,则可以解决Console.Read()背后的许多谜团:

static void Main(string[] args)
{
    var c = Console.Read();
    Console.WriteLine(c);
    c = Console.Read();
    Console.WriteLine(c);
}

在运行程序时,只需在您的键盘上按一次 Enter 键,并在控制台上检查输出。以下是它的样子:

enter image description here

有趣的是,你只按了一次 Enter 键,但它却能够满足我代码片段中的两个 Read() 调用。在 Windows 中,Enter 键会发出两个字符,即回车符(\r - ASCII 码 13)和换行符(\n - ASCII 码 10)。你可以在这篇文章中了解更多信息 - Windows 回车符 \r\n 是由一个字符还是两个字符组成?


0

0

Console.Read() 返回输入字符的字符代码。您需要使用 Convert.ToChar(amount); 将其转换为字符串,然后需要使用 int.Parse() 来获取您要查找的值。


0

不要:

int amount = Console.Read();

尝试:

int amount = 0;
int.TryParse(Console.ReadLine(), out amount);

这是因为你只读取了字符代码,所以例如输入11时,你仍然会得到49。你需要读取字符串值并将其解析为整数值。在上面的代码中,如果输入有误,你将得到0。


0

Console.Read 返回按下的键字符的ASCII值。

如果使用 Console.ReadKey().KeyChar,您将获得表示实际按下的字符的char

然后,您可以使用.ToString()将该字符转换为一个字符字符串。

现在,您有了一个字符串,可以使用int.Parseint.TryParse将完全包含数字字符的字符串转换为整数。

因此,将所有这些放在一起:

int value;
if (int.TryParse(Console.ReadKey().KeyChar.ToString(), out value))
{
    //use `value` here
}
else
{
    //they entered a non-numeric key
}

0
Console.WriteLine("How many students would you like to enter?");
string amount = Console.ReadLine();
int amt = Convert.ToInt32(amount);

Console.WriteLine("{0} {1}", "amount equals", amount);

for (int i = 0; i < amt; i++)
{
    Console.WriteLine("Input the name of a student");
    String StudentName = Console.ReadLine();
    Console.WriteLine("the Students name is " + StudentName);
}
//thats it

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接