Console IO


Console I/O

Console I/O is accomplished through the standard streams Console.In, Console.Out, and Console.Error. Console I/O has been used since Chapter 2, so you already are familiar with it. As you will see, it has some additional capabilities.

Before we begin, however, it is important to emphasize a point made earlier in this book: Most real applications of C# will not be text-based, console programs. Rather, they will be graphically oriented programs or components that rely upon a windowed interface for interaction with the user. Thus, the portion of C#’s I/O system that relates to console input and output is not widely used. Although text-based programs are excellent as teaching examples, for short utility programs, and for some types of components, they are not suitable for most real-world applications.

Reading Console Input

Console.In is an instance of TextReader, and you can use the methods and properties defined by TextReader to access it. However, you will usually use the methods provided by Console, which automatically read from Console.In. Console defines three input methods. The first two, Read( ) and ReadLine( ), have been available since .NET Framework 1.0. The third, ReadKey( ), was added by .NET Framework 2.0.

To read a single character, use the Read( ) method:

 static int Read( )

Read( ) returns the next character read from the console. It waits until the user presses a key and then returns the result. The character is returned as an int, which must be cast to char. Read( ) returns 1 on error. This method will throw an IOException on failure. When using Read( ), console input is line-buffered, so you must press ENTER before any character that you type will be sent to your program.

Here is a program that reads a character from the keyboard using Read( ):

 // Read a character from the keyboard. using System; class KbIn {   public static void Main() {     char ch;     Console.Write("Press a key followed by ENTER: ");     ch = (char) Console.Read(); // get a char     Console.WriteLine("Your key is: " + ch);   } }

Here is a sample run:

 Press a key followed by ENTER: t Your key is: t

The fact that Read( ) is line-buffered is a source of annoyance at times. When you press ENTER, a carriage-return, line-feed sequence is entered into the input stream. Furthermore, these characters are left pending in the input buffer until you read them. Thus, for some applications, you may need to remove them (by reading them) before the next input operation. (To read keystrokes from the console in a non-line-buffered manner, you can use ReadKey( ), described later in this section.)

To read a string of characters, use the ReadLine( ) method. It is shown here:

 static string ReadLine( )

ReadLine( ) reads characters until you press ENTER and returns them in a string object. This method will also throw an IOException on failure.

Here is a program that demonstrates reading a string from Console.In by using ReadLine( ):

 // Input from the console using ReadLine(). using System; class ReadString {   public static void Main() {     string str;     Console.WriteLine("Enter some characters.");     str = Console.ReadLine();     Console.WriteLine("You entered: " + str);   } }

Here is a sample run:

 Enter some characters. This is a test. You entered: This is a test.

Although the Console methods are the easiest way to read from Console.In, you can call methods on the underlying TextReader. For example, here is the preceding program rewritten to use the ReadLine( ) method defined by TextReader:

 // Read a string from the keyboard, using Console.In directly. using System; class ReadChars2 {   public static void Main() {     string str;     Console.WriteLine("Enter some characters.");     str = Console.In.ReadLine(); // call TextReader's ReadLine() method     Console.WriteLine("You entered: " + str);   } }

Notice how ReadLine( ) is now invoked directly on Console.In. The key point here is that if you need access to the methods defined by the TextReader that underlies Console.In, you will invoke those methods as shown in this example.

Using ReadKey( )

Beginning in version 2.0, the .NET Framework has included a method in Console that enables you to read individual keystrokes directly from the keyboard, in a non-line-buffered manner. This method is called ReadKey( ). When it is called, it waits until a key is pressed. When a key is pressed, ReadKey( ) returns the keystroke immediately. The user does not need to press ENTER. Thus, ReadKey( ) allows keystrokes to be read and processed in real time.

ReadKey( ) has these two forms:

 static ConsoleKeyInfo ReadKey( ) static ConsoleKeyInfo ReadKey(bool noDisplay)

The first form waits for a key to be pressed. When that occurs, it returns the key and also displays the key on the screen. The second form also waits for and returns a keypress. However, if noDisplay is true, then the key is not displayed. If noDisplay is false, the key is displayed.

ReadKey( ) returns information about the keypress in an object of type ConsoleKeyInfo, which is a structure. It contains the following read-only properties:

 char KeyChar ConsoleKey Key ConsoleModifiers Modifiers

KeyChar contains the char equivalent of the character that was pressed. Key contains a value from the ConsoleKey enumeration, which is an enumeration of all the keys on the keyboard. Modifiers describes which, if any, of the keyboard modifiers ALT, CTRL, or SHIFT were pressed when the keystroke was generated. These modifiers are represented by the ConsoleModifiers enumeration, which has these values: Control, Shift, and Alt. More than one modifier value might be present in Modifiers.

The major advantage to ReadKey( ) is that it provides a means of achieving interactive keyboard input because it is not line-buffered. To see the effect of this, try the following program:

 // Read keystrokes from the console by // using ReadKey(). using System; class ReadKeys {   public static void Main() {     ConsoleKeyInfo keypress;     Console.WriteLine("Enter keystrokes. Enter Q to stop.");     do {       keypress = Console.ReadKey(); // read keystrokes       Console.WriteLine(" Your key is: " + keypress.KeyChar);       // Check for modifier keys.       if((ConsoleModifiers.Alt & keypress.Modifiers) != 0)         Console.WriteLine("Alt key pressed.");       if((ConsoleModifiers.Control & keypress.Modifiers) != 0)         Console.WriteLine("Control key pressed.");       if((ConsoleModifiers.Shift & keypress.Modifiers) != 0)         Console.WriteLine("Shift key pressed.");     } while(keypress.KeyChar != 'Q');   } }

A sample run is shown here:

 Enter keystrokes. Enter Q to stop. a Your key is: a b Your key is: b d Your key is: d A Your key is: A Shift key pressed. B Your key is: B Shift key pressed. C Your key is: C Shift key pressed.   Your key is: Control key pressed. Q Your key is: Q Shift key pressed.

As the output confirms, each time a key is pressed, ReadKey( ) immediately returns the keypress. As explained, this differs from Read( ) and ReadLine( ), which use line-buffered input. Therefore, if you want to achieve interactive responses from the keyboard, use ReadKey( ).

Writing Console Output

Console.Out and Console.Error are objects of type TextWriter. Console output is most easily accomplished with Write( ) and WriteLine( ), with which you are already familiar. Versions of these methods exist that output for each of the built-in types. Console defines its own versions of Write( ) and WriteLine( ) so that they can be called directly on Console, as you have been doing throughout this book. However, you can invoke these (and other) methods on the TextWriter that underlies Console.Out and Console.Error if you choose.

Here is a program that demonstrates writing to Console.Out and Console.Error:

 // Write to Console.Out and Console.Error. using System; class ErrOut {   public static void Main() {     int a=10, b=0;     int result;     Console.Out.WriteLine("This will generate an exception.");     try {       result = a / b; // generate an exception     } catch(DivideByZeroException exc) {       Console.Error.WriteLine(exc.Message);     }   } }

The output from the program is shown here:

 This will generate an exception. Attempted to divide by zero.

Sometimes newcomers to programming are confused about when to use Console.Error. Since both Console.Out and Console.Error default to writing their output to the console, why are there two different streams? The answer lies in the fact that the standard streams can be redirected to other devices. For example, Console.Error can be redirected to write to a disk file, rather than the screen. Thus, it is possible to direct error output to a log file, for example, without affecting console output. Conversely, if console output is redirected and error output is not, then error messages will appear on the console, where they can be seen. We will examine redirection later, after file I/O has been described.




C# 2.0(c) The Complete Reference
C# 2.0: The Complete Reference (Complete Reference Series)
ISBN: 0072262095
EAN: 2147483647
Year: 2006
Pages: 300

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net