Модуль (или как говорят в случае с Си – хедер) или заголовочный файл iostream призван предоставить средства ввода-вывода, для стандартной консоли. Т.е. то, что вводит с клавиатуры и читает с экрана пользователь.
Все его возможности размещены в пространстве имен std, поэтому для его использования либо приходится приписывать префикс std, либо указывать пространство имен через using namespace
1 2 3 4 | using namespace std; ... cin >> Переменная; cout << "Чет там"; |
Или
1 2 | std::cin >> Переменная; std::cout << "Чет там"; |
В этой статье будем использовать первый вариант – подключение пространства имен через using namespace.
iostream содержит два основных класса:
- cin – для обработки ввода с клавиатуры;
- cout – для вывода в консоль переменных или просто текста;
Есть еще классы cerr и clog, но их в целом, используют не так часто, и о них мы упоминать не будем. Если кому интересно – эти классы используют для вывода ошибок при операциях и для логирования действий.
Сразу скажу, что не всё, что присуще этим классам будет описано. Только самое часто используемое из функционала. Это операторы перенаправления форматированного вывода (<< и >>), которые занимаются выводом значений переменных в зависимости от их типов и указанного формата. Это операторы неформатированного чтения\записи (читай: по байтам или посимвольно), методы get(), put() и write() призванные просто вывести массив символов какими бы они ни были. И операторы форматирования setf(), width(), precision(), которые указывают для текущего вывода, как форматировать выводимое, как выравнивать его, по какой стороне и сколько ставить символов после запятой.
Класс cin
Класс cin содержит множество методов. Все их можно увидеть, если ввести в среде разработки ключевое слово cin и поставить после него точку. Редактор кода предложит все имеющиеся методы этого класса на выбор:
Как сказано выше, для начинающих программистов, мы рассмотрим только некоторые из них.
Класс cin основан на классе istream, и содержит возможность перенаправления ввода. Используя перегрузку оператора >> , класс позволяет указать в какую переменную будет производиться ввод данных.
1 2 3 4 5 | double d; int i; string s; cin >> d >> i >> s; |
Перечисленные в примере переменные получают (считывают) свои данные согласно своим позициям в операции. В данном примере сначала считывается вещественное в d, потом целое в i, и затем строковая переменная. Это нужно обязательно учитывать – неправильная последовательность переменных может дать либо ошибку ввода, либо переменные могут получить данные им не предназначающиеся.
При считывании строки нужно помнить, что если при в ней встретится пробел, считка завершится (в операционной системе принято параметры отделять пробелами). Так удобно разбивать строку на слова. Проиллюстрировать это можно таким примером:
1 2 3 4 5 6 7 8 9 10 | #include <iostream> #include <string> using namespace std; int main() { string s; for (cin >> s; !cin.eof(); cin >> s) cout << s << endl; } |
Из личного опыта я не рекомендую применять именно такой метод деления строки на слова, но знать об этом полезно.
Если нужно считать строку целиком до переноса каретки, стоит использовать рассматриваемый ниже метод getline().
Метод get()
Позволяет ввести символ или строку. При вводе стоки поддерживает разделитель, указанный программистом, до которого будет читаться строка. По умолчанию стоит символ перевода строки '\n' То есть метод get() ждет нажатия клавиши Энтер. Только потом обрабатывает считываемое.
При вводе символа в числовую переменную, метод возвращает код этого символа:
1 2 | int c = cin.get(); // Получаем код символа char c = cin.get(); // Или сам символ |
cin.get() часто ставят в конце программы, чтобы задержать консоль с результатами:
1 2 3 4 | ...... cin.get(); return 0 } |
В классическом Си популярным аналогом является функция getchar() для такой задержки.
Чтобы сделать с помощью этого метода ввод строки, достаточно передать в его параметры указатель на массив символов, куда будет производиться запись, и количество символов, которое ожидается для ввода.
1 2 3 4 5 6 7 8 9 | int n = 10; char *s = new char[n]; cout << "\nВведите строку из 10 символов: "; cin.get(s,n); cout << "Строка: " << s << endl; delete [] s; //Остальное, если строку ввели в размере более n символов - отсекаем (игнорируем) сin.ignore(); |
Схема простая: Передаем указатель на массив символов, передаем количество считываемого, и после нажатия клавиши Энтер, cin.get() считает в этот массив заданное количество символов. Остальные символы считаны не будут, поэтому чтобы освободить от них буфер ввода можно вызвать метод ignore().
Если указать третьим параметром символ-разделитель, cin.get() будет считывать либо сколько заказано символов, либо пока cin не встретит этот символ:
1 | cin.get(s,n,' '); |
Тут в s строку считываются символы вплоть до первого пробела. Если пробелов не обнаружится – считываться будет либо до нажатия Энтер либо до n-ного символа.
Метод getline()
Аналогичен методу get(). Помимо всего, что “умеет” get(), переопределен для строк типа string. Так же как и get() умеет считывать до символа, указанного в качестве разделителя, так же первым параметром указывается массив символов, а вторым количество символов для считывания.
Использование его переопределенной версии в хедере string выглядит так:
1 2 | string s; getline(cin,s); |
Класс cout
Класс cout предполагает вывод данных в консоль. Базовый класс ostream. Основной оператор – перегруженный << Он указывает, какую переменную выводить в консоль.
1 2 3 4 5 | double d = 1; int i = 2; string s = "123"; cout << d << i << s; |
Правила последовательности те же, что у cin – вывод слева направо.
Для перевода каретки на новую строку рекомендуется использовать оператор endl. Или передавать старый добрый ‘\n’
1 | cout << d << i << s << endl; |
1 | cout << d << i << s << '\n'; |
Метод put() выводит символ в консоль:
1 | cout.put('В'); |
Выведет один символ.
Метод write() выведет блок символов из массива символов, переданный ему в качестве указателя
1 2 3 4 5 6 7 8 9 10 | #include <iostream> using namespace std; int main() { char *s = "Hello"; cout.write(s, strlen(s)); cout << endl; cout.write(s, 2); cout << endl; } |
В принципе, в write() можно передавать указатель на любой блок памяти, но для вывода в консоль характерны только массивы читаемых, понятных человеку символов.
Метод width() задает ширину выводимого, если необходимо выровнять до определенного количества символов. Как правило применяется при построении таблиц. Типичный пример: Вывод таблицы вычисления формулы (пример ниже).
Метод precision() указывает сколько цифр будет в дробной части, если выводится вещественная переменная.
Метод setf() определяет, как будет выравниваться (влево, вправо, по центру) выводимое, и в каком формате оно будет.
Комплексный пример этих методов можно увидеть в задании построения таблицы параболы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <iostream> using namespace std; int main() { setlocale(LC_ALL, "rus"); double x; // Указываем дополнить слово "Парабола" до 15 символов пробелами cout.width(15); cout << "Парабола" << endl; // Указываем дополнить слово "Х" до 10 символов пробелами cout.width(10); cout << "X" << endl; // Указываем дополнить слово "Y" до 10 символов пробелами cout.width(10); cout << "Y" << endl; // Указываем что выравниваться выводимое будет справа // Т.е. пробелы дополнятся слева cout.setf(ios::right); for (x = 0; x < 10; x += 1){ cout.width(10); cout << x << '|'; cout.width(10); cout << x*x << '|' << endl; }; } |
16-тиричное представление строки можно вывести, например, вот так :
1 2 3 4 5 6 7 8 9 10 11 | #include <iostream> using namespace std; int main() { char *s = "figaro"; cout.setf(ios::hex, ios::basefield); for (int i = 0; s[i]; i++) cout << (int)s[i] << ' '; cout << endl; } |
А так научный формат представления вещественного:
1 2 3 4 5 6 7 8 | #include <iostream> using namespace std; int main() { cout.setf(ios::scientific); cout << 123.456; cout << endl; } |
Можно задать формат вывода булевских переменных:
1 2 3 4 5 6 7 8 | #include <iostream> using namespace std; int main() { cout << false << endl;//Выведет 0 - целый вид false cout.setf(ios::boolalpha); cout << false << endl; //Выведет строкой "false" } |
Поработайте с методами этих классов самостоятельно. Постарайтесь понять, что делает каждый из них. Такая самостоятельная практика будет вам очень полезна.
Рассылка новых уроков по программированию: |
метод игнорировать().
И операторы форматирования SETF(), ширина(), точность(),
и так дальше. Что за перевод?