Программа курса← C#: Базовый курс
1Знакомство с C# и .NET
2Данные и типы
3Ветвления и циклы
4Методы и ошибки
5Коллекции и строки
6Классы и объекты

Ввод и вывод в консоли

Пока программа ничего не спрашивает и ничего не показывает, убедиться, что она работает, невозможно. Консоль – самый прямой способ увидеть результат: два метода на вывод, один на ввод.

Вывод: WriteLine и Write

Разница между ними ровно одна – перевод строки в конце.

Console.WriteLine("Первая строка");
Console.WriteLine("Вторая строка");

Console.Write("Эти два вызова ");
Console.Write("окажутся на одной строке");

WriteLine без аргументов просто переводит каретку – так вставляют пустую строку между блоками вывода.

Приглашение к вводу пишите через Write, а не WriteLine: тогда курсор останется на той же строке и пользователь будет печатать сразу после вопроса, а не под ним.

Подстановка значений в строку

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

Интерполяция строк – строка начинается с $, а выражения ставятся в фигурных скобках:

string name = "Аня";
int age = 19;

Console.WriteLine($"{name}, вам {age} лет");

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

Console.WriteLine($"Через год будет {age + 1}");
Console.WriteLine($"Имя заглавными: {name.ToUpper()}");

Второй способ – склейка через +. Работает, но читается тяжелее, особенно когда кусков больше двух:

Console.WriteLine(name + ", вам " + age + " лет");

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

Есть и третий вариант – string.Format с нумерованными местами вида {0}. Он старше интерполяции и до сих пор встречается в чужом коде, но самому его выбирать незачем.

Форматирование чисел

После значения через двоеточие можно указать, как его показать:

double price = 1234.5678;

Console.WriteLine($"{price:F2}");     // 1234,57 – два знака после запятой
Console.WriteLine($"{price:N0}");     // 1 235 – с разделителем групп, без дробной части
Console.WriteLine($"{0.257:P1}");     // 25,7 % – проценты
Console.WriteLine($"{DateTime.Now:dd.MM.yyyy}");

Разделителем дробной части в русской локали будет запятая, а не точка: формат зависит от настроек системы, а не от языка программирования.

Ввод: ReadLine

Метод ждёт, пока пользователь наберёт строку и нажмёт Enter, и возвращает набранное:

Console.Write("Как вас зовут? ");
string name = Console.ReadLine();

Console.WriteLine($"Здравствуйте, {name}!");

Возвращается всегда строка. Даже если пользователь ввёл одни цифры, для программы это текст: консоль не знает, что вы собирались получить число.

Console.Write("Сколько вам лет? ");
string input = Console.ReadLine();

int age = int.Parse(input);   // вот теперь это число
Console.WriteLine($"Через год будет {age + 1}");

Без int.Parse строка "19" при попытке прибавить единицу дала бы не 20, а ошибку компиляции: складывать текст с числом C# не станет.

int.Parse падает с исключением, если в строке не число: пользователь ввёл «девятнадцать» – программа аварийно завершилась. Правильный способ – int.TryParse, но у него нужна проверка результата, поэтому разберём его в уроке про преобразования типов.

Как ввод устроен в других языках

Один и тот же диалог. Разница – в том, кто отвечает за тип введённого:

Console.Write("Сколько вам лет? ");
int age = int.Parse(Console.ReadLine());
age = int(input("Сколько вам лет? "))

Обе программы делают одно и то же и обе упадут на нечисловом вводе. Но в C# тип переменной объявлен явно, и, если убрать int.Parse, компилятор откажется собирать программу ещё до запуска. В Python ошибка проявится только когда до неё дойдёт выполнение.

Служебные символы в строках

Некоторые символы нельзя просто напечатать внутри кавычек – их записывают через обратную косую:

Запись Что означает
\n перевод строки
\t табуляция
\" кавычка внутри строки
\\ сама обратная косая

Из-за последнего пункта пути в Windows выглядят неуклюже: "C:\\Users\\Аня\\file.txt". Чтобы не удваивать каждую косую, строку помечают знаком @ – тогда служебные последовательности внутри не действуют:

string path = @"C:\Users\Аня\file.txt";

Знаки @ и $ совмещаются, и порядок с 2021 года любой: $@"..." и @$"..." работают одинаково.

Маленькая программа целиком

Всё, что было в уроке, в одном примере:

Console.Write("Имя: ");
string name = Console.ReadLine();

Console.Write("Год рождения: ");
int year = int.Parse(Console.ReadLine());

int age = DateTime.Now.Year - year;

Console.WriteLine();
Console.WriteLine($"{name}, вам примерно {age} лет.");
Console.WriteLine($"Это {age * 12} месяцев или около {age * 365:N0} дней.");

«Примерно» здесь не из вежливости: мы знаем только год рождения, а не дату, поэтому до дня рождения ответ завышен на единицу. Программа, которая обещает точность, которой у неё нет, – худший вид ошибки: она не падает, ей просто не стоит верить.