6

I have been trying to use Console.Read() and Console.ReadLine() in C# but have been getting weird results. for example this code

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

has been giving me that amount = 49 when I input 1 for the number of students, and Im not even getting a chance to input a student name.

RBT
  • 24,161
  • 21
  • 159
  • 240
Mike Cornell
  • 69
  • 1
  • 1
  • 2

10 Answers10

11

This because you read a char. Use appropriate methods like ReadInt32() that takes care of a correct conversion from the read symbol to the type you wish.

The reason why you get 49 is because it's a char code of the '1' symbol, and not it's integer representation.

char     code
0 :      48
1 :      49
2:       50
...
9:       57

for example: ReadInt32() can look like this:

public static int ReadInt32(string value){
      int val = -1;
      if(!int.TryParse(value, out val))
          return -1;
      return val;
}

and use this like:

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

It Would be really nice to have a possibility to create an extension method, but unfortunately it's not possible to create extension method on static type and Console is a static type.

dna
  • 483
  • 3
  • 10
  • 32
Tigran
  • 61,654
  • 8
  • 86
  • 123
  • `int.TryParse` is simple enough and the elements of your `ReadInt32` method are reused in the calling method that you would be better using the solution presented by Rune FS or Steve. – Trisped Sep 06 '12 at 21:04
  • 1
    @Trisped: If during program flow it happens that I need read several times `integer` from the console, I would prefer to have it inside single method, and call a *method*, rather then spaghetti code everywhere. – Tigran Sep 06 '12 at 21:06
  • If you write out the whole code block using your method you will find that you use the same number of variables and method calls (since you have to validate the input) as if you had just used the `int.TryParse` method. If there was more to it then just converting the string to an int then I would agree, since it is easier/safer to have the code in one method rather then spread across all the places it is used. – Trisped Sep 07 '12 at 00:55
3

Try to change your code in this way

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

Instead to use Read use ReadLine and then check if the user input is really an integer number using Int32.TryParse. If the user doesn't input a valid number repeat the question.
Using Console.Read will limit your input to a single char that need to be converted and checked to be a valid number.

Of course this is a brutal example without any error checking or any kind of safe abort from the loops.

Koopakiller
  • 2,838
  • 3
  • 32
  • 47
Steve
  • 213,761
  • 22
  • 232
  • 286
  • What if he wants the user to be able to type just a single character, rather than entering an entire line? – Servy Sep 06 '12 at 20:53
  • But this will limit the number of students to 9. And nowhere I have read of this requirement. – Steve Sep 06 '12 at 20:55
  • He seems to have gone out of his way to not use `ReadLine`, which would indicate that he only wants a single digit. – Servy Sep 06 '12 at 21:01
  • @Trisped Well, it's clear he doesn't know how `Read` works. It's more a question of, "What about `Read` did he misunderstand?" – Servy Sep 06 '12 at 21:09
3

For someone who might still need this:

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);
     }
}
Koopakiller
  • 2,838
  • 3
  • 32
  • 47
2

you get a character char from read not an int. you will need to make it a string first and parse that as a string. THe implementation could look like the below

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

I've changed it to use readline because readline returns a string an doesn't arbitrarily limits the number of students to 9 (the max number with one digit)

Rune FS
  • 21,497
  • 7
  • 62
  • 96
0

Console.Read() is returning the char code of the character that you enter. You need to use Convert.ToChar(amount); to get the character as a string, and then you will need to do int.Parse() to get the value you're looking for.

w.brian
  • 16,296
  • 14
  • 69
  • 118
0

Instead of:

int amount = Console.Read();

try:

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

Its because You read just character code, so for example typing 11 You will still get 49. You need to read string value and the parse it to int value. With code above in case of bad input You will get 0.

rumburak
  • 1,097
  • 11
  • 19
0

Console.Read returns the asci value of the key character that was pressed.

If you use Console.ReadKey().KeyChar you'll get a char that represents the actual character that was pressed.

You can then turn that character to a one character string by using .ToString().

Now that you have a string you can use int.Parse or int.TryParse to turn a string containing entirely numeric characters into an integer.

So putting it all together:

int value;
if (int.TryParse(Console.ReadKey().KeyChar.ToString(), out value))
{
    //use `value` here
}
else
{
    //they entered a non-numeric key
}
Servy
  • 202,030
  • 26
  • 332
  • 449
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
Koopakiller
  • 2,838
  • 3
  • 32
  • 47
gerald
  • 1
0

Try this:

int amount = ReadInt32();

or if it doesn't work try this:

int amount = Console.ReadInt32();

or this:

int amount = Convert.ToInt32(Console.Readline());

In this, it will read string then it will convert it into Int32 value.

You can also go here: http://www.java2s.com/Tutorials/CSharp/System.IO/BinaryReader/C_BinaryReader_ReadInt32.htm

If nothing works, please let me know.

0

TL;DR; Enter key in Windows isn't a single character. This fact is at the root of many issues related to Console.Read() method.

Complete Details: If you run below piece of code on your computer then you can solve lot of mysteries behind Console.Read():

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

While running the program, hit the Enter key just once on your keyboard and check the output on console. Below is how it looks:

enter image description here

Interestingly you pressed Enter key just once but it was able to cater to two Read() calls in my code snippet. Enter key in windows emits two characters for a new line character namely carriage return (\r - ASCII code 13) and line feed (\n - ASCII code 10). You can read about it more here in this post - Does Windows carriage return \r\n consist of two characters or one character?

RBT
  • 24,161
  • 21
  • 159
  • 240