Console writeline c что это
Перейти к содержимому

Console writeline c что это

  • автор:

Console writeline c что это

Доброго времени суток! В этом уроке мы поговорим о том, как получать данные от пользователя, это очень важный момент для любой компьютерной программы. В принципе, приложение может получать информацию от пользователя (или внешнего мира) разными способами, например, через графический интерфейс пользователя (через различные поля ввода и т.п.), читать из файла, принимать по сети от удаленного источника, ну или как в нашем случае – получать информацию, введенную пользователем с клавиатуры.

Помните, что получение информации от пользователя крайне важный момент, так как большинство ошибок в программах возникают из-за некорректных входных данных, а точнее, из-за недостаточной их обработки.

И так, к делу! Вспомним пример одного из предыдущих уроков, в котором мы в цикле, запрашивали информацию у пользователя, до тех пор, пока он не введет строку «выход». Вот фрагмент исходного кода:

//Переменная для хранения введенной строки string userString = ""; //Цикл с постусловием do < //Приглашение пользователю Console.Write("Введите любую строку и нажмите клавишу Enter: "); /* * Получение веденной с клавиатуры строки, * введенная строка сохраняется в переменную userString */ userString = Console.ReadLine(); //Вывод введенной строки Console.WriteLine("Пользователь ввел строку: " + userString); >while (userString != "выход");

Получение информации с клавиатуры и сохранения этой информации в переменную заключается в одной лишь строке:

userString = Console.ReadLine();

Всё очень просто, после того как пользователь введет строку и нажмет на клавишу «Enter», информация окажется в переменной «userString». Но тут есть один нюанс, операция «Console.ReadLine();» (на самом деле, это вызов метода «ReadLine», класса «Console») возвращает как результат строку. Всё бы ничего, но на практике нам потребуется получать от пользователя не только строки, но и числа, например. Так что, нужно научиться преобразовывать строковые значения в численные. К счастью, в языке C# есть инструмент для преобразования типов. На практике, это выглядит примерно так:

//Получение строки string userString = Console.ReadLine(); //Преобразование строки в число (в тип int) int intValue = Convert.ToInt32(userString);

Для преобразования типов в C# можно использовать класс (позже я расскажу, что такое класс, а пока не забивайте себе голову этим) «Convert», у этого класса есть большое количество методов (функций – если хотите), так вот, метод «ToInt32» принимает один аргумент, в круглых скобках сразу после имени метода, в нашем случае, этот аргумент является строкой, которая и будет преобразована в число (если конечно такую строку можно будет преобразовать в число).

Теперь давайте напишем программу, которая запрашивает у пользователя сначала одно целое число, затем второе, а потом, выводит результат сложения этих чисел в консоль.

Создадим новый проект и напишем следующий код, в методе Main:

//Приглашение пользователю ввести первое число Console.Write("Введите первое число и нажмите клавишу Enter: "); //Получение первой строки string firstString = Console.ReadLine(); //Преобразование первой строки в число int firstArg = Convert.ToInt32(firstString); //Приглашение пользователю ввести второе число Console.Write("Введите второе число и нажмите клавишу Enter: "); //Получение второй строки string secondString = Console.ReadLine(); //Преобразование второй строки в число int secondArg = Convert.ToInt32(secondString); //Сложение двух переменных int result = firstArg + secondArg; //Вывод результата Console.WriteLine("Результат сложения введенных чисел: " + result.ToString()); /* * Обратите внимание на запись result.ToString(), * тут мы преобразовали число в строку, вызвав * метод ToString на переменной result! * Этой операцией мы будем пользоваться часто. */

Обратите внимание на комментарий в самом конце кода! Там рассказывается как перевести число, обратно в строку.

А теперь соберите проект и запустите программу. Затем, введите какое-нибудь целое число (только целое и обязательно число!), например, 25 и нажмите клавишу Enter. Потом введите другое число (хотя, можно и тоже самое), например, 10 и нажмите Enter. В результате вы должны увидеть результат сложения этих чисел! Выглядеть это будет примерно так:

Результат выполнения программы

Результат выполнения программы

На этот раз хватит информации. В следующем уроке мы поговорим как обрабатывать ошибки во время выполнения программы. Например, те, которые могут возникнуть в приведенном выше примере, если пользователь введет не число, а простой текст! Но это уже тема следующего урока…

Консольный ввод-вывод информации с примерами на C# и Windows Terminal

Консоль (Console)- характерная особенность ранних операционных систем (например, MS DOS), использующих интерфейс командной строки для интерактивного обмена информацией с пользователем. Консольные приложения используются и сейчас. По сравнению с графическим интерфейсом, интерфейс командной строки требует меньше системных ресурсов и предоставляет инструменты автоматизации для повторяющихся задач.

Наиболее яркими примерами интерфейсов командной строки (англ. Command line interface, CLI) являются: Командная оболочка Windows, PowerShell, а также Bash, доступная на всех платформах (наибольшее распространение Bash получил в Unix-системах и Mac, присутствует также в компонентах Подсистема Windows для Linux (англ. Windows Subsystem for Linux, WSL)).

В операционной системе Windows консоль называется окном командной строки, для вызова которой Вы можете пройти в меню Пуск — Командная строка. В 2019 году компания Micrsoft также представила Windows Terminal — современное консольное приложение для пользователей инструментов и оболочек командной строки, таких как Command Prompt, PowerShell и WSL.

Форма интерфейсов командной строки используется в основном для обработки сценариев команд с использованием последовательности операций чтения (для принятия данных путем ввода текстовой информации пользователем) и операций записи (в вывод консоли, для отображения результатов обратной связи).

На платформе Microsoft .Net Core такие операции в виде методов описаны в классе System.Console, предоставляющем базовую поддержку для приложений, считывающих и записывающих символы в консоль стандартных входных и выходных потоков.

Программный способ записи в вывод консоли

Для вывода информации на консоль применяются 2 ключевых метода класса Console — Console.WriteLine и Console.Write, отличие которых заключается в том, что WriteLine самостоятельно добавляет терминатор строки (разделитель строки) ко всему, что вы записали. Использование метода Write предполагает ручное разбиение строки на несколько путем добавления в запись вывода терминатора строки, где это необходимо.

Записывает указанные данные с текущим признаком конца строки в стандартный выходной поток.

Console.WriteLine(“Hello, World!”);
Console.WriteLine(“=Second Line=”);

Результатом вывода будет две строки.

Записывает текстовое представление заданного значения или значений в стандартный выходной поток без признака конца строки.

Console.Write(“Hello,”);
Console.Write(“ “);
Console.Write(“World!”);
Console.Write(Environment.NewLine);
Console.Write(“=Second Line=”);

Результат вывода этого примера идентичен.

Во втором примере для разделения строки используется в качестве терминатора свойство Environment.NewLine — это обеспечивает эффективный способ выбора комбинации символов конца строки, которая зависит от используемой вами платформы. Так, большинство Unix-систем применяет специальную комбинацию “\n” в качестве терминатора строки, тогда как Windows-системы “\r\n”.

Формирование строк

При выводе информации вы можете использовать операторы + или += , интерполяцию строк и иные методы для объединения и формирования строковых переменных.

Программный способ ввода информации с консоли

Как и запись в вывод, класс Console предоставляет различные методы для чтения ввода от пользователя.

Метод Console.ReadLine

Считывает набор символов до тех пор, пока не найдет признак окончания или новой строки, и возвращает все, что он считает, как строковое значение.

Console.WriteLine(“What is your name?”);
string response = Console.ReadLine();
Console.WriteLine(“Hello, “ + response+“!“);

Метод Console.Read

Считывает следующий символ в строке и возвращает его как код целочисленного символа.

Console.WriteLine(“Please, type anything: “);
int value = Console.Read();
Console.Write(“You typed: “ + (char)value);

В отличие от ReadLine , метод Read возвращает по одному символу за раз, пока не достигнет конца ввода. Read фактически не возвращает строку, он возвращает целое число, представление ASCII введенного символа. В примере используется функция char() для преобразования полученного целого числа, чтобы получить действительно введенный символ.

Метод Console.ReadKey

Считывает следующий символ в строке и возвращает его как экземпляр ConsoleKeyInfo.

ConsoleKeyInfo описывает нажатую клавишу, включая символ, представленный этой клавишей, и состояние управляющих клавиш-модификаторов (например, Shift, Alt и др.). Нижеследующий пример ожидает нажатия клавиши Enter.

while (Console.ReadKey().Key != ConsoleKey.Enter) <>

Быстрый консольный ввод на .NET

Во времена, когда .NET был закрытой технологией только для Windows, за ним и языком C# закрепилась репутация платформы, которая отлично подходит для решения бизнес-задач, но непригодна для соревновательного программирования и написания высокопроизводительного кода.

Часто приходится слышать, что «шарпы медленные», особенно в контексте алгоритмических задач, например с timus.online и codeforces.com. И, увы, не только слышать, но и сталкиваться с реальными проблемами, связанными с особенностями платформы, получая Wrong Answer, Runtime Error, Memory Limit, Time Limit при корректном алгоритме.

Большинство этих проблем кроется в особенностях консольного ввода и вывода. Да и часто куда проще написать cin >> n или sc.nextInt() , чем int.Parse(Console.ReadLine()) или Console.ReadLine().Split().Select(int.Parse).ToArray() , из-за чего выбор падает на другой язык.

Далее я расскажу о распространённых проблемах с консольным вводом-выводом в .NET, и о том, как сделать ввод быстрым и удобным.

Плавающая запятая

Иногда требуется считать или вывести число с плавающей точкой. Но легко забыть, что плавающие точки в .NET бывают запятыми, в зависимости от локали. Об этом особенно легко забыть, если пользоваться английской локалью в своей операционной системе.

Варианта решения два:

  • задать локаль потока: Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
  • передавать CultureInfo.InvariantCulture явно в такие методы, как (Try)Parse и ToString

Также в современном .NET есть параметр рантайма InvariantGlobalization , позволяющий избежать подобных проблем.

Ввод и вывод

Представим, что нам дана простая задача: нужно считать строк по 4 числа int в каждой , числа разделены пробелами. Требуется вывести сумму чисел для каждой строки.

int n = int.Parse(Console.ReadLine()); for (int i = 0; i

Может ли в этом коде что-то привести к вердикту, отличному от Accepted? Запросто.

Особенности форматирования

В условии ничего не сказано про количество пробелов, которыми разделены числа. И в итоге, если где-то пробелов больше одного, Console.ReadLine().Split() вернёт массив, содержащий пустые строки. А int.Parse упадёт с исключением, что приведёт к вердикту Runtime Error. Может показаться, что такого не бывает на контестах, но увы, случай вполне реальный.

int n = int.Parse(Console.ReadLine()); for (int i = 0; i

Неприятный нюанс, о котором надо помнить. Кстати, если раньше код обрабатывал все пробельные символы как разделители, то теперь только пробелы. Исправить можно, но будет чуть длиннее.

Проблема возникает только при построчном чтении ввода. В языках, где есть готовые способы для считывания с консоли чисел (например int n; cin >> n ), проблемы не возникает вообще.

Console Flush

Потоки ввода и вывода stdin/stdout/stderr устроены на основе буфера в памяти, в который один процесс может записать данные, а другой — прочитать. Обращаться к этому буферу ради нескольких байт — дорого, поэтому для эффективности каждый процесс может дополнительно буферизовать ввод/вывод. Продвижение данных в буфер потока происходит либо при заполнении локального, либо при вызове .Flush() .

Вызов .Flush() имеет большой смысл для интерактивных консольных приложений — пользователю нужно показать вывод в терминале сразу, а не копить его в памяти. Большинство платформ изначально адаптированы под этот сценарий и вызывают .Flush() автоматически после каждой записи.

Обратите внимание, что бывают и задачи, в которых требуется интерактивный ввод-вывод (request-response семантика). Например задачи, в которых требуется вычислить ответ, задавая «вопросы» проверяющей системе (простейший пример — программа, угадывающее слово в условном «Поле чудес», «общающаяся» с программой-ведущим)

Чтобы сэкономить на Flush, в C++ iostreams пишут:

std::ios::sync_with_stdio(false); std::cin.tie(nullptr);

А в C# можно использовать StreamWriter для stdout вместо Console :

const int bufferSize = 16384; using var input = new StreamReader( Console.OpenStandardInput(), bufferSize: bufferSize); using var output = new StreamWriter( Console.OpenStandardOutput(), bufferSize: bufferSize); int n = int.Parse(input.ReadLine()); for (int i = 0; i

Проверим, оказывает ли .Flush() влияние на производительность замерами. Версия с Console.WriteLine отрабатывает на моём компьютере за ~490ms, а с использованием StreamWriter — за 105ms. Т.е. причина плохой производительности оказалась вовсе не в LINQ. В проверяющей системе c более медленным железом можно запросто получить Time Limit Exceed, если не учитывать автоматический .Flush() . Кстати, на заметку, в энтерпрайз приложениях проблема тоже встречается — в логировании.

Замерял на Linux, рантайм .NET 7 NativeAOT — так достигается минимальный оверхед на старте программы, порядка 1.5 ms. На Windows как минимум старт процесса был бы порядка 10 ms, даже для C++.

Для чтения также можно использовать StreamReader вместо Console . Это позволяет сэкономить на проверке, не переопределён ли Console.In при каждом чтении и использовать увеличенный буфер, но выигрыш куда менее впечатляющий — единицы миллисекунд

Обратите внимание, что задавать размер буфера консольному стриму нет смысла — параметр попросту игнорируется

Задача на ввод: аллокации

Задача 1510 с Тимуса. Для этой задачи есть два решения — за линию и с сортировкой. Её все сдают легко на том же C++, но на C# даже с умным алгоритмом из-за особенностей стандартного ввода будет Memory Limit Exceed. Почему?

В задаче установлен Memory Limit в 16 MB. Зачем? Не знаю, сохранить все числа в памяти и отсортировать он никак не мешает, ведь 500000 чисел по 4 байта — всего лишь 2 MB. Но в C# чтение ввода через Console.ReadLine приводит к аллокации строк. А строка с числом из 10 цифр, это не 4 байта, а, как минимум:

  • 16 байт на заголовок объекта и указатель на Method Table
  • 4 байта на хранение длины
  • 20 байт на 10 символов в UTF-16
  • 2 байта на null terminator для совместимости с нативным кодом, его ожидающим

Т.е. уже 42 байта на 10 символов. А 500000 раз по 42 байта — это уже 21 MB.

Но они же короткоживущие?! Читаем строку, сразу парсим, GC как-нибудь соберёт. Но срабатывание GC — не гарантированно, освобождение памяти обратно в ОС — тоже, а принудительный вызов через GC.Collect() может привести уже к Time Limit Exceed.

Как же быть? Писать ввод самостоятельно

Кастомный ввод

Дедовское решение

По C++ вспоминается решение с посимвольным чтением чисел.

Перепишем его на C# с использованием Console.Read() , а лучше — StreamReader.Read() . В этом случае использовать StreamReader оправдано, потому что обращаться к Console на каждый символ гораздо дороже, чем на каждую строку при использовании ReadLine .

После этого задача не представляет никакой сложности. На моём компьютере посимвольное чтение отрабатывает в 3 раза быстрее, чем с Console.ReadLine() .

fastscan

StreamReader reader = new StreamReader(Console.OpenStandardInput(), bufferSize: 32768); int fastscan() < bool negative = false; bool read_start = false; int number = 0; while (true) < int c = reader.Read(); if (c=='-') < negative = true; read_start = true; continue; >if (c>47 && c <58) < number = number * 10 + (c - 48); read_start = true; continue; >if (read_start) break; > if (negative) number *= -1; return number; >

Решение, однако, не идеально. Этот метод подходит для целых чисел, а сделать корректный парсинг чисел с плавающей точкой нетривиально, легко попасть на граничные случаи и ошибиться с точностью. Чтобы это понять, достаточно посмотреть Pull Request.

Тиктокерское решение

В современном .NET есть перегрузки методов Parse и TryParse принимающие ReadOnlySpan вместо строки. Вместо ручного парсинга чисел, можно записать фрагмент символов с числом в буфер и вызвать стандартный метод для парсинга.

Это решит проблему с парсингом чисел с плавающей точкой «дедовского» решения, а также сделает ввод кода удобнее, избавив от необходимости писать конструкции вида Console.ReadLine().Split().Select(int.Parse).ToArray() . Сам код настолько прост, что может быть легко написан прямо во время контеста (но не учитывает, например, переполнение буфера, если вам это важно):

SpanScanner

class Scanner < StreamReader input = new(Console.OpenStandardInput(), bufferSize: 16384); char[] buffer = new char[4096]; public int ReadInt() < var length = PrepareToken(); return int.Parse(buffer.AsSpan(0, length)); >private int PrepareToken() < int length = 0; bool readStart = false; while (true) < int ch = input.Read(); if (ch == -1) break; if (char.IsWhiteSpace((char)ch)) < if (readStart) break; continue; >readStart = true; buffer[length++] = (char)ch; > return length; > >
Program Lang Compiler Mean (Int) Mean (Double)
fastscan C++ g++64 14 ms
fastscan C# NativeAOT 22 ms
Span C# NativeAOT 38 ms 85 ms
cin C++ g++64 38 ms 101 ms
scanf C++ g++64 44 ms 70 ms
Console.ReadLine C# NativeAOT 64 ms 117 ms

Да, работает медленнее «дедовского» варианта, но на уровне с общепринятыми способами ввода, не аллоцирует memory traffic, и уж точно не станет причиной попадания в Time или Memory Limit.

На C++ и других языках можно написать и более эффективные варианты консольного ввода. scanf и cin взяты только для того, чтобы ориентироваться на способы чтения ввода, которые обычно укладываются в пределы Time Limit

Для .NET 7 и C# 11 можно сделать generic версию на основе статического метода интерфейса ISpanParsable . Правда, в проверяющих системах C# 11 ещё не поддерживается.

SpanParsableScanner

class Scanner < StreamReader input = new(Console.OpenStandardInput(), bufferSize: 16384); char[] buffer = new char[4096]; public T Read() where T : ISpanParsable  < var length = PrepareToken(); return T.Parse(buffer.AsSpan(0, length), CultureInfo.InvariantCulture); >private int PrepareToken() < int length = 0; bool readStart = false; while (true) < int ch = input.Read(); if (ch == -1) break; if (char.IsWhiteSpace((char)ch)) < if (readStart) break; continue; >readStart = true; buffer[length++] = (char)ch; > return length; > >

Также я подготовил более эффективный вариант кода на основе TryParse(ReadOnlySpan) , но он слишком длинный, чтобы поместиться здесь. Он разгоняется в моём тесте до 24 мс за счёт чтения данных блоками.

Отказываемся от StreamReader

StreamReader — прослойка между Console Stream, в который обычно попадают ASCII-символы и .NET-строками в кодировке UTF-16. Переделаем код для работы со Stream напрямую.

Метод для парсинга, принимающий ReadOnlySpan уже не подойдёт. К счастью, в .NET есть класс под названием Utf8Parser — наследие разработки библиотеки System.Text.Json , решающее ту же задачу для спана байтов. Не обманывайтесь тем, что в названии есть Utf8 — парсить все 100500 цифр, которые есть в Unicode он не умеет. Зато с обычными ASCII-цифрами справляется на ура!

Достоинство Utf8Parser.TryParse в сравнении с T.TryParse — возможность парсить значение с префикса, без заранее подготовленного токена. Сравните:

bool TryParse(ReadOnlySpan span, out int value, IFormatProvider provider); bool TryParse(ReadOnlySpan span, out int value, out int bytesConsumed, char format='\0')

Первый метод заставляет заранее заглянуть вперёд и найти разделитель. Затем данные читаются снова для парсинга.

Второй же умеет останавливаться при парсинге токена сам, позволяя распарсить данные за один проход по буферу.

Т.к. Utf8Parser — достаточно узкоспециализированный класс, он не поддерживает IFormatProvider и локали. Но нам это только в радость — десятичная запятая нам здесь никак не помешает.

При использовании Utf8Parser нужно учитывать, что если данных в буфере осталось мало — результат может оказаться неверным. Если какой-то из текстовых токенов разобьётся на два разных чтения из потока данных, например [. 12][34. ] , то Utf8Parser прочитает этот токен как два разных числа — 12 и 34. Или же для [. 1e][7. ] вернётся false для 1e , и придётся делать дополнительную проверку: или это невалидный double или же просто не хватило данных.

Для упрощения реализации, буду требовать наличия в буфере некоторого минимального количества данных или признака окончания потока данных. Сам код тоже довольно прост и занимается только загрузкой данных из потока и пропуском разделителей, которыми здесь считаются все символы по пробел включительно. По желанию можно также пропускать символы, например, с кодами >= 128 , на случай если в поток данных попадёт мусор.

Но во время контеста я бы лучше использовал предыдущий вариант на основе StreamReader и Span — он всё же гораздо проще

AsciiScanner

class Scanner < private const int MaxTokenLength = 1200; Stream? input = Console.OpenStandardInput(); byte[] buffer = new byte[32768]; SpanFragment => buffer.AsSpan(offset, length - offset); int offset; int length; public int ReadInt() < while (input != null && length - offset < MaxTokenLength) < if (offset != 0) < var remaining = Fragment.Length; Fragment.CopyTo(buffer); offset = 0; length = remaining; >var count = input.Read(buffer, length, buffer.Length - length); if (count length += count; while (offset < length && buffer[offset] while (offset < length && buffer[offset] void Throw() => throw new Exception(); >

Замеры

Program Lang Compiler Mean (Int) Mean (Double)
Utf8Parser C# NativeAOT 10 ms 40 ms
fastscan C++ g++64 14 ms
fastscan C# NativeAOT 22 ms
SpanBlock C# NativeAOT 24 ms 72 ms
Span C# NativeAOT 38 ms 85 ms
cin C++ g++64 38 ms 101 ms
scanf C++ g++64 44 ms 70 ms
Console.ReadLine C# NativeAOT 64 ms 117 ms

В качестве тестовых данных использовался файл с 200000 строками шестизначных чисел по 4 числа в каждой (~5MB). Каждая программа считала XOR каждой из колонок и выводила ответ в конце. Таким образом, тестировалась только производительность ввода рассмотренными способами, с возможностью проверить корректность при тестировании. Входные данные предварительно загружались в память программы, производящей запуск тестируемых программ и подавались на stdin.

В качестве рантайма использовался .NET 7 NativeAOT на Linux. Этот вариант даёт меньше всего оверхеда на старте программы. C JIT на Windows оверхед составил ~36 мс, на Linux — ~70. Очерёдность по скорости для .NET-программ на Windows не отличается.

Тест не претендует на максимальную корректность, ставилась лишь цель оценить порядок разницы между способами чтения ввода.

Выводы

  • На .NET можно писать программы с интенсивным консольным IO.
  • Для достижения максимальной производительности рекомендуется:
    • не использовать статические методы Console.Write/WriteLine , а писать в stdout через StreamWriter
    • для чтения большого количества чисел с консоли (или просто для удобства написания кода) использовать описанные способы: например с дополнительным буфером и неаллоцирующим TryParse(ReadOnlySpan)
    • правильно оценивать задачу и не переусложнять код без необходимости

    Ссылки

    • API Proposal о новом консольном вводе

    C#. Урок 3. Консольный ввод\вывод

    Follow us on Google Plus Follow us on rss

    Backend-разработка и создание утилит командной строки невозможно без консольного ввода\вывода. В рамках данной статьи будут рассмотрены методы класса Console для чтения и записи информации в консоль.

    • Консольный ввод\вывод
    • Класс Console. Вывод данных в консоль
      • Метод Write
      • Метод WriteLine
      • Метод Read
      • Метод ReadLine
      • Метод ReadKey

      Исходный код примеров из этой статьи можете скачать из нашего github-репозитория.

      Консольный ввод\вывод

      Все приложения условно можно разделить на две группы: консольные и с графическим интерфейсом пользователя. Ко второй группе относится большая часть приложений, с которыми работают пользователи в операционной системе Windows, на смартфонах и в вебе. Под консольными будем понимать приложения, которые запускаются через терминал (командную строку), их взаимодействие с пользователем происходит в текстовом режиме. Практически все приложения, которые запускаются на стороне сервера можно отнести к этой группе. Для организации ввода\вывода информации при работе с консолью в C# используется класс Console.

      Класс Console. Вывод данных в консоль

      Класс Console содержит методы для работы с консольным вводом\выводом, управлением потоком с ошибками и окном консоли. Начнем с вывода информации в консоль, для решения этой задачи класс Console предоставляет два метода: Write и WriteLine.

      Для знакомства с методами класса Console создайте в удобном для вас каталоге проект с именем CSharpLesson3:

      > dotnet new console -o CSharpLesson3

      Метод Write

      Метод Write – направляет в стандартный выходной поток текстовое представление переданного в него объекта. Дополнительно, предоставляет возможность задать форматирование.

      Откройте файл Program.cs в созданном ранее проекте и добавьте в метод Main следующие строки, демонстрирующие работу с методом Write:

      // Примеры работы с методом Write без форматирования Console.Write("Текущая дата: "); Console.Write(DateTime.Now); Console.Write("\n"); Console.Write($"Текущая дата: \n"); // Примеры работы с методом Write с использованием форматирования Console.Write("Текущая дата: \n", DateTime.Now); Console.Write("Число: \n", 123.456789);

      Более подробно про форматирование будет написано в уроке, посвященном работе со строками.

      Сохраните документ, откройте консоль, перейдите в каталог с проектом и выполните команду:

      > dotnet run

      Результат работы программы будет выглядеть примерно следующим образом:

      Текущая дата: 16.10.2020 11:48:28 Текущая дата: 16.10.2020 11:48:28 Текущая дата: 16.10.2020 11:48:28 Текущая дата: 1,234568E+002

      Обратите внимание на первые три вызова метода Write, если не поставить символ перевода строки, то данные будут выдаваться в одну строку друг за другом, это не всегда удобно. Если требуется, чтобы вывод каждый раз осуществлялся с новой строки, то воспользуйтесь методом WriteLine.

      Метод WriteLine

      Метод WriteLine записывает указанные данные в выходной поток и добавляет символ перевода строки. Добавьте в программу следующие строки:

      Console.WriteLine("Текущая дата: "); Console.WriteLine(DateTime.Now);

      Теперь надпись “Текущая дата:” и дата со временем будут выведены в разных строках.
      WriteLine (также как Write) может принимать не только строковые значения, но и переменные разных типов:

      DateTime nowDate = DateTime.Now; string someText = "Сегодня"; int number = 924; Console.WriteLine(nowDate); Console.WriteLine(someText); Console.WriteLine(number);

      Удобным и наглядным способом вывода значений переменных в консоль с дополнительным текстовым пояснением является использование строковой интерполяции:

      Console.WriteLine($" . Число: ");

      Запустите проект и в консоли увидите результат выполнения программы:

      Сегодня 26.08.2020 11:53:44. Число: 924

      Прием интерполяции позволяет внутри строки, используя фигурные скобки, указывать имена переменных, которые будут заменены значениями. Перед такой строкой ставится знак $.
      Методы WriteLine и Write позволяют использовать форматирование:

      Console.WriteLine(":, Число: ", nowDate, someText, number);

      В этом случае методу передается ряд параметров, первый – это строка, в которой, в фигурных скобках, указывается порядок подстановки значений переменных, далее, через запятую, перечисляются переменные, значения которых нужно подставить, здесь важен порядок: нумерация начинается с 0.

      Класс Console. Чтение данных из консоли

      В классе Console, помимо рассмотренных выше методов вывода в консоль, присутствуют методы для считывания вводимых данных из консоли.

      Метод Read

      Метод Read возвращает числовой код последнего введенного символа во входном потоке, если символ введен не был, то будет возвращен код -1. Для завершения работы метода, после ввода символа необходимо нажать клавишу “Enter”. Рассмотрим работу с методом Read на примере:

      Console.WriteLine("Нажмите любую клавишу, а затем Enter"); int key1 = Console.Read(); Console.WriteLine($"Код нажатой клавиши: "); Console.WriteLine("Символьное представление: " + Convert.ToChar(key1));

      Если после надписи “Нажмите любую клавишу, а затем Enter” будет введено более одного символа, то Read вернет только первый.

      Для представления кода в виде символа необходимо переменную key1 привести к типу Char, для этого можно воспользоваться методом Convert.ToChar().

      Метод ReadLine

      Метод ReadLine возвращает введенную строку символов до нажатия клавиши “Enter”. Добавим несколько строк в файл с исходным кодом, для демонстрации работы с методом ReadLine :

      Console.WriteLine("Введите ваше имя, а затем нажмите Enter"); string name = Console.ReadLine(); Console.WriteLine($"Привет, !");

      Если необходимо получить с консоли численные данные, то следует воспользоваться методами из класса Convert для приведения типа String к соответствующему числовому типу:

      Console.WriteLine("Сколько вам лет?"); int age = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("Ваш рост в см?"); int height = Convert.ToInt32(Console.ReadLine()); Console.WriteLine("Привет , вам уже полных лет и ваш рост см", name, age, height);

      Метод ReadKey

      ReadKey возвращает объект класса ConsoleKeyInfo, в который помещается информация о нажатой клавише. Этот метод, как правило, используют для остановки выполнения программы или чтобы получить ответ от пользователя. Добавим строки для работы с ReadKey:

      Console.WriteLine("Нажмите любую клавишу:"); var key2 = Console.ReadKey(); Console.WriteLine(key2.Key); Console.WriteLine(key2.KeyChar);

      Исходный код примеров из этой статьи можете скачать из нашего github-репозитория.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *