Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная работа 7new.rtf
Скачиваний:
3
Добавлен:
09.11.2019
Размер:
294.5 Кб
Скачать

Встроенные типы.

Прямо поддерживаемые типы для вставки: char (signed и unsigned), short (signed и unsigned), int (signed и unsigned), long (signed и unsigned), char* (интерпретируется как строка), float, double, long double и void*. Целые типы преобразуются в соответствии с правилами по умолчанию для printf (если только Вы не изменили эти правила с помощью флагов ios). Например, для объявлений int i; long l;, операторы

cout<<i<<" "<<l;

printf("%d %ld", i, l);

дают одинаковый результат.

Вставка указателя (void*) так же предопределена:

int i = 1;

cout<<&i; // выводит указатель в 16-ричном виде.

Форматированный вывод.

Форматирование для ввода и вывода определяется флагами (манипуляторами) формата, определенными в классе ios. Флаги определены:

public:

enum {

skipws = 0x0001, // пропускает пробелы при вводе

left = 0x0002, // выровненный слева вывод

right = 0x0004, // выровненный справа вывод

internal = 0x0008, // заполнение после указателя знака или базы

dec = 0x0010, // десятичное преобразование

oct = 0x0020, // восьмеричное преобразование

hex = 0x0040, // шестнадцатиричное преобразование

showbase = 0x0080, // показывает указатель базы на вывод

showpoint = 0x0100, // показывает десятичную точку (вывод fp)

uppercase = 0x0200, // вывод в 16-ричном формате прописными буквами

showpos = 0x0400, // показывает '+' с положительными целыми числами

scientific = 0x0800, // использует 1.2345Е2 fp представление и вывод Е

fixed = 0x1000, // использует 123.45 fp представление

unitbuf = 0x2000, // освобождает все потоки после вставки

stdio = 0x4000 // освобождает stdout, stderr после вставки

};

Эти флаги читаются и устанавливаются с помощью элементов-функций rdstate и clear соответственно. Пример применения приведен ниже.

Манипуляции.

Более простой способ изменить некоторые из переменных формата - в использовании специального оператора, называемого манипулятором. Манипуляторы используют поток как аргумент и возвращают ссылку на тот же поток, следовательно манипуляторы могут быть включены в цепочку вывода (или ввода) для изменения состояния потока в качестве побочного эффекта, без действительного вывода (или ввода). Например

cout<<setw(4)<<i<<setw(6)<<j;

эквивалентно

cout.width(4);

cout<<i;

cout.width(6);

cout<<j;

setw - это параметризованный манипулятор, объявленный в iomanip.h. Другие параметризованные манипуляторы setbase, setfill, setprecision, setiosflags и resetiosflags работают так же. Чтобы использовать их в Вашей программе должен быть включен iomanip.h. Вы можете написать собственные манипуляторы без параметров:

ostream& dingy( ostream& os)

{

return os << "\a\a";

}

...

cout << i << dingy << j;

Непараметризованные манипуляторы dec, hex и oct (объявленные в iostream.h) не имеют параметров и просто изменяют основание преобразования (и оставляют ее измененной):

int i = 36;

cout << dec << i << " "

<< hex << i << "

<< oct << i << endl;

// показывает 36 24 44

Определенный пользователем вывод.

Вы можете перегрузить оператор << для вывода Ваших типов данных. Предположим, у Вас есть тип

struct info {

char *name;

double val;

char *units;

};

Вы можете перегрузить <<:

ostream& operator << (ostream& s, info& m) {

s << m.name << " " m.val << " " << m.units;

}

операторы

info x;

...

// инициализация х

...

cout << x;

будут выводить "capacity 1.25 liters".

Ввод.

Входной поток аналогичен выходному, но использует перегруженный оператор сдвига вправо >>, известный как оператор извлечения (получить из). Левый операнд >> - это объект типа класс и stream. Как и для вывода, правый оператор может быть любого типа, для которого был определен входной поток.

По умолчанию >> пропускает разделители (определенные функцией isspace в ctype.h), затем читает символы, соответствующие типу входного объекта. Пропуск разделителей управляется флагом ios::skipws в перечислении состояния формата. Флаг skipws обычно установлен на пропуск разделителей. Очистка этого флага (например через setf) выключает пропуск разделителей. Заметим так же, что манипулятор ws позволяет Вам удалить разделители.

Рассмотрим следующий пример:

int i;

double d;

cin >> i >> d;

Последняя строка приводит к пропуску разделителей; цифры, читаемые со стандартного ввода (по умолчанию с клавиатуры) затем преобразуются во внутреннюю двоичную форму и сохраняются в переменной i; пропускается больше разделителей, и, наконец, читается число с плавающей точкой, преобразуется и сохраняется в переменной d.

Для типа char (signed или unsigned) действие оператора >> заключается в том, что пропускается разделитель и запоминается следующий символ (не-разделитель). Если Вам нужно читать следующий символ, независимо от того, является ли он разделителем или нет, Вы можете использовать одну из элементов-функций get.

Для символа char* (рассматриваемого как строка), оператор >> пропускает разделитель и запоминает следующие символы (не-разделители) до тех пор, пока не встретится другой символ разделителя. Затем добавляется завершающий нулевой символ. Необходимо избегать "переполнения" строки. Можно изменить длину по умолчанию (0, означающий отсутствие предела) используя setw следующим образом:

char array[SIZE];

...

// инициализация массива

...

cin.width(sizeof(array));

cin >> array;

Для ввода со встроенными типами, если конец ввода происходит до появления любого символа не-разделителя, то в buf не запоминается ничего, а состояние istream устанавливается в "fail". Таким образом, если выход был не инициализирован, то он остается не инициализированным.