Страница 203 из 502
<b>// Считать символы, введенные с консоли, используя метод ReadKey().</b>
<b>using System;</b>
<b>class ReadKeys {</b>
<b> static void Main() {</b>
<b> ConsoleKeyInfo keypress;</b>
<b> Console.WriteLine("Введите несколько символов, " +</b>
<b> "а по окончании - <Q>.");</b>
<b> do {</b>
<b> keypress = Console.ReadKey(); // считать данные о нажатых клавишах </b>
<b> Console.WriteLine(" Вы нажали клавишу: " + keypress.KeyChar);</b>
<b> // Проверить нажатие модифицирующих клавиш.</b>
<b> if((ConsoleModifiers.Alt & keypress.Modifiers) != 0)</b>
<b> Console.WriteLine("Нажата клавиша <Alt>.");</b>
<b> if((ConsoleModifiers.Control & keypress.Modifiers) != 0)</b>
<b> Console.WriteLine("Нажата клавиша <Control>.");</b>
<b> if((ConsoleModifiers.Shift & keypress.Modifiers) != 0)</b>
<b> Console.WriteLine("Нажата клавиша <Shift>.");</b>
<b> } while(keypress.KeyChar != 'Q');</b>
<b> }</b>
<b>}</b>
Вот, например, к какому результату может привести выполнение этой программы.
<b>Введите несколько символов, а по окончании - <Q>.</b>
<b>а Вы нажали клавишу: а</b>
<b>b Вы нажали клавишу: b</b>
<b>d Вы нажали клавишу: d</b>
<b>А Вы нажали клавишу: А</b>
<b>Нажата клавиша <Shift>.</b>
<b>В Вы нажали клавишу: В</b>
<b>Нажата клавиша <Shift>.</b>
<b>С Вы нажали клавишу: С</b>
<b>Нажата клавиша <Shift>.</b>
<b>• Вы нажали клавишу: •</b>
<b>Нажата клавиша <Control>.</b>
<b>Q Вы нажали клавишу: Q</b>
<b>Нажата клавиша <Shift>.</b>
Как следует из приведенного выше результата, всякий раз, когда нажимается клавиша, метод ReadKey() немедленно возвращает введенный с клавиатуры символ. Этим он отличается от упоминавшегося ранее метода Read(), в котором ввод выполняется с построчной буферизацией. Поэтому если требуется добиться в программе реакции на ввод с клавиатуры, то рекомендуется выбрать метод ReadKey().
Потоки Console.Out и Console.Error являются объектами типа TextWriter. Вывод на консоль проще всего осуществить с помощью методов Write() и WriteLine(), с которыми вы уже знакомы. Существуют варианты этих методов для вывода данных каждого из встроенных типов. В классе Console определяются его собственные варианты метода Write() и WriteLine(), и поэтому они могут вызываться непосредственно для класса Console, как это было уже не раз показано на страницах данной книги. Но при желании эти и другие методы могут быть вызваны и для класса TextWriter, который является базовым для потоков Console.Out и Console.Error.
Ниже приведен пример программы, в котором демонстрируется вывод в потоки Console.Out и Console.Error. По умолчанию данные в обоих случаях выводятся на консоль.
<b>// Организовать вывод в потоки Console.Out и Console.Error.</b>
<b>using System;</b>
<b>class ErrOut {</b>
<b> static void Main() {</b>
<b> int a=10, b=0; </b>
<b> int result;</b>
<b> Console.Out.WriteLine("Деление на нуль приведет " +</b>
<b> "к исключительной ситуации.");</b>
<b> try {</b>
<b> result = a / b; // сгенерировать исключение при попытке деления на нуль</b>
<b> } catch(DivideByZeroException exc) {</b>
<b> Console.Error.WriteLine(exc.Message);</b>
<b> }</b>
<b> }</b>
<b>}</b>
При выполнении этой программы получается следующий результат.
<b>Деление на нуль приведет к исключительной ситуации.</b>
<b>Попытка деления на нуль.</b>
Начинающие программисты порой испытывают затруднения при использовании потока Console.Error. Перед ними невольно встает вопрос: если оба потока, Console.Out и Console.Error, по умолчанию выводят результат на консоль, то зачем нужны два разных потока вывода? Ответ на этот вопрос заключается в том, что стандартные потоки могут быть переадресованы на другие устройства. Так, поток Console.Error можно переадресовать в выходной файл на диске, а не на экран. Это, например, означает, что сорбщения об ошибках могут быть направлены в файл журнала регистрации, не мешая выводу на консоль. И наоборот, если вывод на консоль переадресуется, а вывод сообщений об ошибках остается прежним, то на консоли появятся сообщения об ошибках, а не выводимые на нее данные. Мы еще вернемся к вопросу переадресации после рассмотрения файлового ввода-вывода.