1.5 – Знакомство с iostream: cout, cin и endl
В этом уроке мы подробнее поговорим о std::cout
, который мы использовали в нашей программе «Hello world!» для вывода в консоль текста «Hello world!». А также узнаем, как получить данные от пользователя, которые мы будем использовать, чтобы сделать наши программы более интерактивными.
Библиотека ввода/вывода
Библиотека ввода/вывода (библиотека io) является частью стандартной библиотеки C++, которая имеет дело с базовым вводом и выводом. Мы будем использовать функции этой библиотеки для получения ввода с клавиатуры и вывода данных в консоль. Буквы io в iostream
означают «input/output» (ввод/вывод).
Чтобы использовать функции, определенные в библиотеке iostream
, нам нужно включить заголовочный файл iostream
в начало любого исходного файла, который использует содержимое, определенное в iostream
, например:
#include <iostream>
// остальной код использует функциональность iostream
std::cout
Библиотека iostream
содержит несколько предопределенных переменных, которые мы можем использовать. Одной из наиболее полезных является std::cout
, которая позволяет нам отправлять данные в консоль для печати в виде текста. cout
означает «character output» (вывод символов).
Вспомним нашу программу Hello world:
#include <iostream> // для std::cout
int main()
{
std::cout << "Hello world!"; // выводим в консоль Hello world!
return 0;
}
В эту программу мы включили iostream
, чтобы у нас был доступ к std::cout
. Внутри нашей функции main()
мы используем std::cout
вместе с оператором вставки (<<
) для отправки текста «Hello world!» в консоль для печати.
std::cout
может печатать не только текст, но и числа:
#include <iostream> // для std::cout
int main()
{
std::cout << 4; // выводим 4 в консоль
return 0;
}
Это дает результат:
4
Его также можно использовать для вывода значений переменных:
#include <iostream> // для std::cout
int main()
{
int x{5}; // определяем целочисленную переменную x, инициализированную значением 5
std::cout << x; // выводим значение x (5) в консоль
return 0;
}
Это дает результат:
5
Чтобы напечатать несколько элементов в одной строке, для объединения (связывания) нескольких частей выводимых данных, оператор вставки (<<
) можно использовать несколько раз в одном выражении. Например:
#include <iostream> // для std::cout
int main()
{
std::cout << "Hello" << " world!";
return 0;
}
Эта программа печатает:
Hello world!
Вот еще один пример, в котором мы печатаем и текст, и значение переменной в одном выражении:
#include <iostream> // для std::cout
int main()
{
int x{5};
std::cout << "x is equal to: " << x;
return 0;
}
Эта программа печатает:
x is equal to: 5
std::endl
Как вы думаете, что напечатает следующая программа?
#include <iostream> // для std::cout
int main()
{
std::cout << "Hi!";
std::cout << "My name is Alex.";
return 0;
}
Результат может вас удивить:
Hi!My name is Alex.
Отдельные выражения вывода не приводят к отдельным выводимым строкам в консоли.
Если мы хотим выводить в консоль отдельные выводимые строки, нам нужно указать консоли, когда необходимо переместить курсор на следующую строку.
Один из способов сделать это – использовать std::endl
. При выводе с помощью std::cout
, std::endl
выводит в консоль символ новой строки (заставляя курсор переместиться в начало следующей строки). В этом контексте endl
означает «end line» (конец строки).
Например:
#include <iostream> // для std::cout и std::endl
int main()
{
std::cout << "Hi!" << std::endl; // std::endl заставит курсор переместиться на следующую строку консоли
std::cout << "My name is Alex." << std::endl;
return 0;
}
Это печатает:
Hi!
My name is Alex.
Совет
В приведенной выше программе второй std::endl
технически не нужен, так как программа сразу же после этого завершается. Однако он служит двум полезным целям: во-первых, он помогает указать, что строка вывода является «законченной мыслью». Во-вторых, если мы позже захотим добавить дополнительные выражения вывода, нам не нужно будет изменять существующий код. Мы можем просто добавить новые выражения.
std::endl
против '\n'
Использование std::endl
может быть немного неэффективным, поскольку фактически выполняет две задачи: перемещает курсор на следующую строку и «очищает» вывод (обеспечивает немедленное отображение на экране). При записи текста в консоль с использованием std::cout
, std::cout
обычно всё равно очищает вывод (а если нет, это обычно не имеет значения), поэтому наличие очистки от std::endl
редко бывает важным.
Из-за этого обычно предпочтительнее использовать символ '\n'. Символ '\n' перемещает курсор на следующую строку, но не выполняет избыточную очистку, поэтому он работает лучше. Символ '\n' также легче читать, поскольку он короче и может быть встроен в существующий текст.
Вот пример, в котором '\n' используется двумя разными способами:
#include <iostream> // для std::cout
int main()
{
int x{5};
// Использование '\n' в одиночном режиме
std::cout << "x is equal to: " << x << '\n';
// Использование '\n', встроенного во фрагменте текста, заключенном в двойные кавычки
// (примечание: при таком использовании одинарные кавычки не используются)
std::cout << "And that's all, folks!\n";
}
Этот код напечатает:
x is equal to: 5
And that's all, folks!
Обратите внимание, что когда '\n' используется сам по себе для перемещения курсора на следующую строку, необходимы одинарные кавычки. При встраивании в текст, который уже заключен в двойные кавычки, одинарные кавычки не нужны.
Мы рассмотрим, что такое '\n' более подробно, когда перейдем к уроку о символах (4.11 – Символы).
Лучшая практика
При выводе текста в консоль лучше использовать '\n' вместо std::endl
.
Предупреждение
'\n' использует обратный слеш (как и все специальные символы в C++), а не прямой слеш. Использование прямого слеша (например, '/n') может привести к неожиданному поведению.
std::cin
std::cin
– еще одна предопределенная переменная, определенная в библиотеке iostream
. В то время как std::cout
выводит данные в консоль с помощью оператора вставки (<<
), std::cin
(что означает «character input», «ввод символов») считывает ввод с клавиатуры с помощью оператора извлечения (>>
). Для дальнейшего использования входные данные должны быть сохранены в переменной.
#include <iostream> // для std::cout и std::cin
int main()
{
// запрашиваем у пользователя число
std::cout << "Enter a number: ";
// определяем переменную x для хранения пользовательского ввода (и инициализируем ее нулем)
int x{ };
// получаем число с клавиатуры и сохраняем его в переменной x
std::cin >> x;
std::cout << "You entered " << x << '\n';
return 0;
}
Попробуйте скомпилировать эту программу и запустить ее самостоятельно. Когда вы запустите программу, строка 6 напечатает «Enter a number: ». Когда код дойдет до строки 10, ваша программа будет ждать, пока вы введете данные. После того, как вы введете число (и нажмете клавишу Enter), введенное вами число будет присвоено переменной x
. Наконец, в строке 11 программа напечатает «You entered », а затем число, которое вы только что ввели.
Например (я ввел 4):
Enter a number: 4
You entered 4
Это простой способ получить от пользователя ввод с клавиатуры, и в будущем мы будем использовать его во многих наших примерах. Обратите внимание, что вам не нужно использовать '\n' при принятии входных данных, так как пользователю нужно будет нажать клавишу Enter, чтобы его входные данне были принят, а это переместит курсор на следующую строку.
Если ваш экран закрывается сразу после ввода числа, обратитесь к уроку «0.8 – Несколько основных проблем C++» для решения этой проблем.
Лучшая практика
Существуют споры о том, нужно ли инициализировать переменную непосредственно перед тем, как передать ей значение, предоставленное пользователем, через другой источник (например, std::cin
), поскольку значение, предоставленное пользователем, просто перезапишет значение инициализации. В соответствии с нашей предыдущей рекомендацией о том, что переменные всегда следует инициализировать, лучше всего сначала инициализировать переменную.
Мы обсудим, как std::cin
обрабатывает недопустимые входные данные в следующем уроке (7.16 – std::cin
и обработка недопустимых входных данных).
Для продвинутых читателей
Библиотека ввода/вывода C++ не позволяет принимать ввод с клавиатуры без нажатия пользователем клавиши Enter. Но если вам это нужно, то вам придется использовать стороннюю библиотеку. Для консольных приложений мы рекомендуем библиотеку pdcurses. Многие графические пользовательские библиотеки имеют для этого свои собственные функции.
Резюме
Программисты-новички часто путают std::cin
, std::cout
, оператор вставки (<<
) и оператор извлечения (>>
). Вот простой способ запомнить:
std::cin
иstd::cout
всегда идут в левой части выражения;std::cout
используется для вывода значения (cout = character output);std::cin
используется для получения входного значения (cin = character input);<<
используется сstd::cout
и показывает направление движения данных (еслиstd::cout
представляет консоль, выходные данные перемещаются из переменной в консоль).std::cout << 4
перемещает значение 4 в консоль;>>
используется сstd::cin
и показывает направление движения данных (еслиstd::cin
представляет клавиатуру, входные данные перемещаются с клавиатуры в переменную).std::cin >> x
перемещает значение, введенное пользователем с клавиатуры, вx
.
Подробнее об операторах мы поговорим в уроке «1.9 – Знакомство с литералами и операторами».
Небольшой тест
Вопрос 1
Рассмотрим следующую программу, которую мы использовали выше:
#include <iostream> // для std::cout и std::cin
int main()
{
// запрашиваем у пользователя число
std::cout << "Enter a number: ";
// определяем переменную x для хранения пользовательского ввода (и инициализируем ее нулем)
int x{ };
// получаем число с клавиатуры и сохраняем его в переменной x
std::cin >> x;
std::cout << "You entered " << x << '\n';
return 0;
}
Программа ожидает, что вы введете целочисленное значение, поскольку переменная x
, в которую будет помещен пользовательские входные данные, является целочисленной переменной.
Запустите эту программу несколько раз и опишите, что произойдет, если вместо этого вы введете следующие типы входных данных:
а) Буква, например, h.
Ответ
х равно 0.
б) Число с дробной частью. Попробуйте числа с дробными составляющими меньше 0,5 и больше 0,5 (например, 3,2 и 3,7).
Ответ
Дробная составляющая опущена.
в) Небольшое отрицательное целое число, например -3.
Ответ
Всё прекрасно работает.
г) Слово, например «Hello».
Ответ
х равно 0.
д) Действительно большое число (минимум 3 миллиарда).
Ответ
Вы получаете, казалось бы, случайное число.
Последнее предложение может быть особенно неожиданным. Попробуйте! Это происходит потому, что x
может содержать числа только до определенного размера. После этого он «переполняется». Мы обсудим переполнение в следующем уроке.