4. Input and Output

There is one important shortcoming with the program above. It doesn't interact with the user. Every time it's used, the programmer must edit the source code to supply the desired values, recompile, and run to get the result. We need a way for the program to get input from the user at run time, so the program doesn't have to be modified to work for other values.

Console applications get input from the user with the help of the Console.ReadLine() method. Here's a simple program that asks the user for his name, and then greets him:

Example 2.3. Hello.cs

using System;

class Hello
{
               
  static void Main()
  {
    // create a string variable
    string username;
    
    // Ask user for name
    Console.Write("Enter your name:");
    username = Console.ReadLine();
    
    // Greet the user
    Console.Write("Hello, ");
    Console.Write(username);
                 
  }
}

Notice particularly the following line:

username = Console.ReadLine();

When the computer encounters this line at runtime, it stops and waits for the user to type in some information and press enter. After the user presses enter, the data entered by the user is stored in the variable username. If you run the program, you might see something like this (emphasized text represents user input):

Enter your name:Fred
Hello, Fred 

For another example, have a look at Area2, an enhanced version of the original Area program that asks the user for the width, height, and units at run time.

Example 2.4. Area2.cs

// Area2.cs
// Calculates the area of a rectangle

using System;

class Area2 { 
  static void Main() { 

    int width, height, area;
    string units;
    
    Console.Write("Enter the width: ");
    width = Convert.ToInt32(Console.ReadLine());
    Console.Write("Enter the height: ");
    height = Convert.ToInt32(Console.ReadLine());
    Console.Write("Enter the units: ");   
    units = Console.ReadLine();
    
    area = width * height;
        
    Console.Write("A rectangle ");
    Console.Write(width);
    Console.Write(units);
    Console.Write(" by ");
    Console.Write(height);
    Console.Write(units);
    Console.Write(" has an area of ");
    Console.Write(area);
    Console.WriteLine(units);    

  } // main
} // Area2

When executed, the program prompts the user for input, and waits for the user to provide the information. For example, here's how a sample run might look (emphasized text represents user input):

Enter the width: 30
Enter the height: 20
Enter the units: mm
A rectangle 30mm by 20mm has an area of 600mm

This program is similar in many ways to the earlier version. The only lines that have changed are the assignment statements. For example, the following statement in Area.cs

width = 30;

was replaced with the lines

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

The Write() method prompts the user to enter some information, and the next line waits for the user to type in a response. The number entered by the user is then stored in the width variable. This is the typical way C# console applications get input from the user: they display a prompt using the Write() method, then they read the user's response.

Take a closer look at the line that reads the width. You might have expected this:

width = Console.ReadLine();

However, that won't work. ReadLine() gets the input and returns it as a string. Since width is not a string variable, the data must be converted to an int using the Convert.ToInt32() method.

There's another matter we need to deal with. Remember what I told you belongs on the right-hand side of an assignment statement? Something called an "expression", right? Remember my definition of expression? "An expression is a formula that produces a value." "But wait," you say, "Console.ReadLine() isn't a formula, is it? It's a method!" Well, it's time to broaden your understanding of what an expression can contain.

Remember what you know about expressions:

It's time to add a new item to the list:

I won't go into the full implications of this here, but there are a couple of things you should try to get nailed down now.

  1. Some methods produce values when they are called, and others don't. Methods that produce values should be used in an expression (usually in an assignment statement). Methods that do not produce values may not be used in an expression; they must always be used in a statement by themselves.

  2. How do you know whether a method produces a value or not? For now, just remember that the Write() and WriteLine() methods do not produce a value, and ReadLine() produces a value. That's why every time you see a Write() method used, it's in a statement by itself, but every time you see a ReadLine() method used, it's in an expression in an assignment statement.