
- •1.2 Философские замечания
- •1.3 Процедурное программирование
- •1.4 Модульное программирование
- •1.5 Абстракция данных
- •1.6 Пределы абстракции данных
- •1.7 Объектно-ориентированное программирование
- •1.8 Концепции объектно-ориентированного программирования
- •1.8.1 Инкапсуляция
- •1.8.2 Полиморфизм
- •1.8.3 Наследование
- •1.10 Несколько полезных советов
- •2.2 Перегрузка функций
- •2.3 Перегрузка операторов
- •2.4 Наследование
- •2.5 Конструкторы и деструкторы
- •2.7 Два новых типа данных
- •Глава 3. Классы и объекты
- •3.1 Параметризованные конструкторы
- •3.2 Дружественные функции
- •3.3 Значения аргументов функции по умолчанию
- •3.3.1 Корректное использование аргументов по умолчанию
- •3.4 Взаимосвязь классов и структур
- •3.5 Связь объединений и классов
- •3.6 Анонимные объединения
- •3.7 Inline-функции
- •3.7.1 Создание inline-функций внутри класса
- •3.8 Передача объектов в функции
- •3.9 Возвращение объектов функциями
- •3.10 Присваивание объектов
- •3.11 Конструктор копирования
- •3.12 Массивы объектов
- •3.12.1 Инициализация массивов объектов
- •3.12.2 Создание инициализированных и неинициализированных массивов
- •3.13 Указатели на объекты
- •3.14 Статические члены класса
- •Глава 4. Перегрузка функций и операторов
- •4.1 Перегрузка конструкторов
- •4.2 Локализация переменных
- •4.3 Локализация создания объектов
- •4.4 Перегрузка функций и неопределенность
- •4.5 Определение адреса перегруженной функции
- •4.6 Указатель this
- •4.7 Перегрузка операторов
- •4.8 Дружественная функция-оператор
- •4.9 Ссылки
- •4.9.1 Параметры-ссылки
- •4.9.2 Передача ссылок на объекты
- •4.9.3 Возврат ссылок
- •4.9.4 Независимые ссылки
- •4.9.5 Использование ссылок для перегрузки унарных операторов
- •4.10 Перегрузка оператора []
- •4.11 Создание функций преобразования типов
- •Глава 5. Наследование, виртуальные функции и полиморфизм
- •5.1 Наследование и спецификаторы доступа
- •5.1.1 Спецификаторы доступа
- •5.1.2 Спецификатор доступа при наследовании базового класса
- •5.1.3 Дополнительная спецификация доступа при наследовании
- •5.2 Конструкторы и деструкторы производных классов
- •5.3 Множественное наследование
- •5.4 Передача параметров в базовый класс
- •5.5 Указатели и ссылки на производные типы
- •5.6 Ссылки на производные классы
- •5.7 Виртуальные функции
- •5.8 Для чего нужны виртуальные функции?
- •5.9 Чисто виртуальные функции и абстрактные типы
- •5.10 Виртуальный базовый класс
- •5.11 Раннее и позднее связывание
- •Глава 6. Подсистема динамического выделения памяти
- •6.1 Введение в обработку исключений
- •6.1.1 Перехват всех исключений
- •6.2 Работа с памятью с помощью new и delete
- •6.3 Размещение объектов
- •6.4 Перегрузка new u delete
- •7.1.1 Потоки
- •7.3 Создание собственных операторов вставки и извлечения
- •7.3.1 Создание операторов вставки
- •7.3.2 Перегрузка операторов извлечения
- •7.4 Форматирование ввода/вывода
- •7.4.1 Форматирование с помощью функций-членов класса ios
- •7.4.2 Использование манипуляторов
- •7.5 Создание собственных функций-манипуляторов
- •7.5.1 Создание манипуляторов без параметров
- •7.5.2 Создание манипуляторов с параметрами
- •7.6 Файловый ввод/вывод
- •7.6.1 Открытие и закрытие файлов
- •7.6.2 Чтение и запись в текстовые файлы
- •7.6.3 Двоичный ввод/вывод
- •7.6.4 Определение конца файла
- •7.6.5 Произвольный доступ
- •Глава 8. Ввод/вывод в массивы
- •8.1 Классы ввода/вывода в массивы
- •8.2 Создание потока вывода
- •8.3 Ввод из массива
- •8.4 Использование функций-членов класса ios
- •8.5 Потоки ввода/вывода в массивы
- •8.6 Произвольный доступ в массив
- •8.7 Использование динамических массивов
- •8.8 Манипуляторы и ввод/вывод в массив
- •8.9 Собственные операторы извлечения и вставки
- •8.10 Форматирование на основе массивов
- •Глава 9. Шаблоны и библиотека stl
- •9.1 Функции-шаблоны
- •9.2 Функции с двумя типами-шаблонами
- •9.3 Ограничения на функции-шаблоны
- •9.4 Классы-шаблоны
- •9.5 Пример с двумя типами-шаблонами
- •9.6 Обзор библиотеки stl
- •9.7 Класс vector
- •9.7 Класс string
- •9.8 Класс list
8.3 Ввод из массива
Для того, чтобы связать поток ввода с массивом, используется следующий конструктор класса istrstream:
istrstream istr(char *buf);
Здесь buf представляет собой указатель на массив, который будет использоваться как источник символов всякий раз при выполнении ввода из потока istr. Массив, на который указывает указатель buf, должен завершаться нулевым символом. Однако нулевой символ никогда не читается из массива.
Ниже приведен пример, использующий строку в качестве ввода:
#include <strstrea.h>
#include <iostream.h>
int main()
{
char s[] = "One 2 3.00";
istrstream ins(s);
int i;
char str[80];
float f;
// чтение: one 2
ins >> str;
ins >> i;
cout << str << " " << i << endl;
// чтение 3.00
ins >> f;
cout << f << '\n';
return 0;
}
Если необходимо, чтобы только часть строки была использована для ввода, то надо применить следующую форму конструктора istrstream:
istrstream istr(char *buf, int size);
Здесь только первые size элементов массива будут использованы для ввода. Эта строка не обязательно должна оканчиваться нулевым символом, поскольку именно величина size определяет размер строки.
Связанный с памятью поток ведет себя точно так же, как потоки, связанные с устройствами. Например, следующая программа иллюстрирует способ, с помощью которого может быть прочитан текст, оканчивающийся нулевым символом в массиве. Когда достигается конец массива, поток ins принимает значение NULL.
#include <strstrea.h>
#include <iostream.h>
int main()
{
char s[] = "C++ arrays are fun! 123.23 0x23\n";
istrstream ins(s);
char ch;
ins.unsetf(ios::skipws); // не пропускать пробелы
while(ins) // нуль в случае достижения конца массива
{
ins >> ch;
cout << ch;
}
return 0;
}
8.4 Использование функций-членов класса ios
Доступ к потокам на основе массивов может быть также осуществлен с помощью стандартных функций-членов класса ios, таких как get() и put(). Также можно использовать функцию eof() для того, чтобы определить, когда будет достигнут конец массива. Например, следующая программа показывает, как прочитать содержимое массива с использованием функции get():
#include <strstrea.h>
#include <iostream.h>
int main()
{
char s[] = "This is a test array\23\22\21\a\t\n";
istrstream ins(s);
char ch;
while(!ins.eof())
{
ins.get(ch);
cout << ch;
}
return 0;
}
В данном примере величины, форматированные следующим образом \23\22\21 являются нетекстовыми управляющими символами CTRL-W, CTRL-V и CTRL-U. Знак \t является символом табуляции. Таким образом могут быть прочитаны данные любого типа.
Если необходимо прочесть данные из буфера, то можно использовать функцию-член read(). Для записи данных в буфер используется функция write().
8.5 Потоки ввода/вывода в массивы
Для создания потока, способного вводить и выводить данные в массив, надо использовать следующий конструктор класса strstream:
strstream iostr(char *buf, int size, int mode);
Здесь buf указывает на строку, используемую для операций ввода/вывода. Величина size содержит размер массива. Параметр mode служит для определения режима. Для нормальных операций ввода/вывода параметру mode присваивается значение ios::in | ios::out. Для ввода массив должен оканчиваться нулем.
Следующая программа использует массив для ввода и для вывода:
#include <strstrea.h>
#include <iostream.h>
int main()
{
char iostr[80];
strstream i(iostr, sizeof(iostr), ios::in | ios::out);
int a, b;
char str[80];
i << "1734 534abcdefghijklmnopqrstuvwxyz";
ios >> a >> b >> str;
cout << a << " " << b << " " << str << endl;
}
Эта программа сначала пишет два числа и буквы алфавита в массив, а затем читает их.