- •Обзорные лекции по курсу
- •1.Потоки
- •1.1. Заголовочные файлы библиотеки потоков iostream
- •1.2. Классы и объекты потоков ввода-вывода
- •2.Вывод потоков
- •Int main()
- •3. Ввод потоков
- •Int X, у;
- •Int с;
- •Сохранение типов данных при вводе-выводе
- •4. Неформатированный ввод-вывод с использованием read, gcount и write
- •5. Манипуляторы потоков
- •Манипуляторы, определяемые пользователем
- •Упражнения для самопроверки
Сохранение типов данных при вводе-выводе
Язык С++ обеспечивает сохранение типов данных при вводе-выводе потоков. Операции « и » перегружены так, чтобы принимать элементы данных заданных типов. Если обрабатываются непредусмотренные данные, то устанавливаются различные флаги ошибок, с помощью которых пользователь может определить, были ли операции ввода-вывода успешными, или нет. Таким способом программа контролирует типы.
4. Неформатированный ввод-вывод с использованием read, gcount и write
Неформатированный ввод-вывод выполняется с помощью функций-элементов read и write. Каждая из них вводит или выводит некоторое число байтов в символьный массив в памяти или из него. Эти байты не подвергаются какому-либо форматированию. Они просто вводятся или выводятся в качестве сырых байтов данных. Например, вызов
char buffer[ ] = "ПОЗДРАВЛЯЕМ С ДНЕМ РОЖДЕНИЯ"; cout.write(buffer, 12);
выводит первые 12 байтов символьного массива buffer (включая нулевые символы, которые могут быть выведены в cout и завершить операцию «). Поскольку символьная строка указывает на адрес своего первого символа, то вызов
cout.write("ABCDEFGYIJKLMNOPQRSTUVWXYZ", 10);
отобразит на экране первые 10 символов алфавита.
Функция-элемент read вводит в символьный массив указанное число символов. Если считывается меньшее количество символов, то устанавливается флаг failbit. Позже мы увидим, каким образом определять, установлен ли флаг failbit.
Функция-элемент gcount сообщает о количестве символов, прочитанных последней операцией ввода.
Ниже приведена программа, демонстрирующая работу функций-элементов read и gcount класса istream и функции-элемента write класса ostream. Программа вводит 20 символов (из более длинной входной последовательности) в массив символов buffer с помощью функции-элемента read, определяет число введенных символов с помощью gcount и выводит символьный массив buffer с помощью write.
// Неформатированный ввод-вывод
// с помощью функций-элементов read, gcount и write.
#include <iostream.h>
const int SIZE = 80;
main ( )
{
char buffer[SIZE] ;
cout « "Введите предложение:" « endl;
cin.read(buffer, 20);
cout « endl « "Введенное предложение: " « endl;
cout . write (buffer, cin . gcount ( ) ) ;
cout « endl;
return 0;
}
5. Манипуляторы потоков
В языке С++ имеется возможность использовать манипуляторы потоков, которые решают задачи форматирования. Манипуляторы потоков позволяют выполнять следующие операции: задание ширины полей, задание точности, установку и сброс флагов формата, задание заполняющего символа полей, сброс потоков, вставку в выходной поток символа новой строки и сброс потока, вставку нулевого символа в выходной поток и пропуск символов разделителей во входном потоке.
Более подробные сведения о манипуляторах приведены ниже.
Манипуляторы потоков dec, oct, hex и setbase, задающие основание чисел
Целые числа обычно интерпретируются как десятичные (с основанием 10). Для изменения основания интерпретации целых чисел в потоке запишите манипулятор hex, чтобы установить шестнадцатеричный формат представления элементов данных (с основанием 16), или запишите манипулятор oct, чтобы установить восьмеричный формат представления данных (с основанием 8). Запишите манипулятор dec для возврата к основанию потока 10.
Основание потока может быть также изменено с помощью манипулятора потока setbase, который принимает один целый параметр со значениями 10, 8 или 16, задающими соответствующие основания системы счисления. Поскольку манипулятор setbase принимает параметр, он называется параметризованным манипулятором потока. Использование манипулятора setbase или любого другого параметризованного манипулятора требует включение заголовочного файла <iomanip.h>. Основание потока остается установленным до тех пор, пока оно не будет изменено явным образом. Пример.
// Использование манипуляторов потока hex, oct, dec и setbase.
#include <iostream.h>
#include <iomanip.h>
int main()
{
int n;
cout « "Введите десятичное число: ";
cin » n;
cout « n « " в шестнадцатеричном формате равно " « hex « n « endl
« dec « n « " в восьмеричном формате равно " « oct « n « endl
« setbase(10) « n « " в десятичном формате равно " « n « endl;
return 0;
}
Точность чисел с плавающей запятой (precision, setprecision)
Мы можем управлять точностью печатаемых чисел с плавающей запятой, т.е. числом разрядов справа от десятичной точки, используя манипулятор потока precision или функцию-элемент setprecision. Вызов любой из этих установок точности действует для всех последующих операций вывода до тех пор, пока не будет произведена следующая установка точности. Функция-элемент precision не имеет никаких аргументов и возвращает текущее значение точности. Приведенная ниже программа использует как функцию-элемент precision, так и манипулятор setprecision для печати таблицы корня квадратного из числа 2 с точностью, варьирующейся от 0 до 9. Отметим, что точность 0 имеет особое значение. Она восстанавливает точность по умолчанию, равную 6.
Ширина поля (setw, width)
Функция-элемент width класса ios устанавливает ширину поля (т.е. число символьных позиций, в которые значение будет выведено, или число символов, которые будут введены) и возвращает предыдущую ширину поля. Если обрабатываемые значения имеют меньше символов, чем заданная ширина поля, то для заполнения лишних позиций используются заполняющие символы: Если число символов в обрабатываемом значении больше, чем заданная ширина поля, то лишние символы не отсекаются и число будет напечатано полностью. Установка ширины поля влияет только на следующую операцию поместить или взять; затем ширина поля устанавливается неявным образом на 0, т.е. поле для представления выходных значений будет просто такой ширины, которая необходима. Функция width, не имеющая аргументов, возвращает текущую установку.
// Управление точностью печати значений с плавающей запятой
#include <iostream.h>
#include <iomanip.h>
#include <math.h>
main()
{
double root2 = sqrt(2.0);
cout « "Корень квадратный из 2 с точностью 0 - 9." « endl « "Точность, установлена с помощью " « "функции-элемента precision:" « endl;
for (int places = 0; places <= 9; places++)
{ cout.precision(places); cout « root2 « endl;
}
cout « endl «"Точность установлена с помощью " « "манипулятора setprecision:" « endl;
for (places = 0; places <= 9; places++)
{cout « setprecision(places) « root2 <<endl;
}
return 0;
}
Нижеприведенная программа демонстрирует использование функции-элемента width при вводе и при выводе. Обратите внимание, что читается по крайней мере на один символ меньше, чем установленная ширина поля, чтобы обеспечить размещение во входной строке нулевого символа. Помните, что операция взять из потока завершается, когда встречаются не лидирующий символ разделитель (т.е. не предшествующий значащим символам).
Для установки ширины поля может быть также использован манипулятор потока setw.
// Демонстрация функции-элемента width
#include <iostream.h>
main ( )
{
int w = 4;
char string[10];
cout « "Введите предложение:" « endl;
cin.width(5);
while (cin » string)
{ cout.width(w++);
cout « string « endl;
cin.width(5);
}
return 0;
}