Организация ввода- вывода в С++ Обмен данными между программой и внешними устройствами осуществляется с помощью операций ввода-вывода. Типичными внешними устройствами являются консоль и жесткий или гибкий диск на котором расположены файлы. В языке Си++ нет особых операторов для ввода или вывода данных. Вместо этого имеется набор классов, стандартно поставляемых вместе с компилятором, которые и реализуют основные операции ввода-вывода. Библиотека классов для ввода-вывода решает две задачи. Вопервых, она обеспечивает эффективный ввод-вывод всех встроенных типов и простое, но тем не менее гибкое, определение операций ввода-вывода для новых типов, разрабатываемых программистом. Во-вторых, сама библиотека позволяет при необходимости развивать её и модифицировать. Потоки Механизм для ввода-вывода в Си++ называется потоком. Название произошло от того, что информация вводится и выводится в виде потока байтов – символ за символом. Класс istream реализует поток ввода, класс ostream – поток вывода. Эти классы определены в файле заголовков ostream.h. Библиотека потоков ввода-вывода определяет три глобальных объекта: cout, cin и cerr сout называется стандартным выводом, cin – стандартным вводом, cerr – стандартным потоком сообщений об ошибках. сout и cerr выводят на консоль и принадлежат к классу ostream, cin имеет тип istream и вводит с консоли. 1 Операции << и >> для потоков Вывод осуществляется с помощью операции <<, ввод с помощью операции >>. В классах iostream операции >> и << определены для всех встроенных типов языка Си++ и для строк (тип char* ). Манипуляторы и форматирование ввода-вывода Часто бывает необходимо вывести строку или число в определенном формате. Для этого используются так называемые манипуляторы. Манипуляторы – это объекты особых типов, которые управляют тем, как ostream или istream обрабатывают endl ends flush dec oct hex setw (int n) setfill(int n) при выводе перейти на новую строку; вывести нулевой байт (признак конца строки символов); немедленно вывести и опустошить все промежуточные буферы; выводить числа в десятичной системе (действует по умолчанию); выводить числа в восьмеричной системе; выводить числа в шестнадцатиричной системе счисления; установить ширину поля вывода в n символов ( n – целое число); установить символ-заполнитель; этим символом выводимое значение будет дополняться до необходимой ширины; 2 setprecision(int установить количество цифр после запятой при n) выводе вещественных чисел; setbase(int n) установить систему счисления для вывода чисел; n может принимать значения 0, 2, 8, 10, 16, причем 0 означает систему счисления по умолчанию, т.е. 10. Использовать манипуляторы просто – их надо вывести в выходной поток. Предположим, мы хотим вывести одно и то же число в разных системах счисления: int x = 53; cout << "Десятичный вид: " << dec << x << endl << "Восьмиричный вид: " << oct << x << endl << "Шестнадцатиричный вид: " << hex << x << endl Аналогично используются манипуляторы с параметрами. Вывод числа с разным количеством цифр после запятой: double x; // вывести число в поле общей шириной // 6 символов (3 цифры до запятой, // десятичная точка и 2 цифры после запятой) cout << setw(6) << setprecision(2) << fixed << x << endl; Те же манипуляторы (за исключением endl и ends ) могут использоваться и при вводе. В этом случае они описывают представление вводимых чисел. Кроме того, имеется манипулятор, работающий только при вводе, это ws. Данный манипулятор переключает вводимый поток в такой режим, при котором все 3 пробелы (включая табуляцию, переводы строки, переводы каретки и переводы страницы) будут вводиться. Ввод-вывод файлов Ввод-вывод файлов может выполняться как с помощью стандартных функций библиотеки Си, так и с помощью потоков ввода-вывода. Функции библиотеки Си являются функциями низкого уровня, без всякого контроля типов. Файл рассматривается как последовательность байтов. Чтение или запись выполняются последовательно. Например, при чтении мы начинаем с начала файла. Предположим, первая операция чтения ввела 4 байта, интерпретированные как целое число. Тогда следующая операция чтения начнет ввод с пятого байта, и так далее до конца файла. Аналогично происходит запись в файл – по умолчанию первая запись производится в конец имеющегося файла, а все последующие операции записи последовательно пишут данные друг за другом. При операциях чтения-записи говорят, что существует текущая позиция, начиная с которой будет производиться следующая операция. В библиотеке Си++ для ввода-вывода файлов существуют классы ofstream (вывод) и ifstream (ввод). Оба они выведены из класса fstream. Сами операции ввода-вывода выполняются так же, как и для других потоков– операции > и < определены для класса fstream как "ввести" и "вывести" соответствующее значение. Различия заключаются в том, как создаются объекты и как они привязываются к нужным файлам. 4 Пример Программа читает из файла” aplusb.in ” два числа и сумму чисел записывает в файл “aplusb.out” #include <fstream> int main() { // открыть файлы std::ifstream input("aplusb.in"); std::ofstream output("aplusb.out"); // прочитать входные данные int a, b; input >> a >> b; // записать результат output << a + b; return 0; } 5