Скачать презентацию
Идет загрузка презентации. Пожалуйста, подождите
Презентация была опубликована 9 лет назад пользователемВладимир Шарапов
1 Программирование в C++ Преподаватель Колотова Людмила Павловна
2 Содержание 10-го занятия по практике 2 Потоки и файлы. Потоковые классы. Класс istream. Класс ostream. Потоковый ввод/вывод дисковых файлов Файловый ввод/вывод с помощью методов
3 Потоковые классы 3 Поток это общее название потока данных. В C++ поток представляет собой объект некоторого класса. Именно поэтому вы могли встретить в листингах потоковые объекты cin и cout. Разные потоки предназначены для представления разных видов данных.
4 Преимущества потоков 4 Одним из аргументов в пользу потоков является простота использования. Каждый объект сам знает, как он должен выглядеть на экране. Это избавляет программиста от одного из основных источников ошибок. Другой причиной является то, что можно перегружать стандартные операторы и функции вставки ( >) для работы с создаваемыми классами. Это позволяет работать с собственными классами как со стандартными типами, что, опять же, делает программирование проще и избавляет от множества ошибок. Оказывается, потоковый ввод/вывод, нужен. Потому что это лучший способ записывать данные в файл, лучший способ организации данных в памяти для последующего использования при вводе/выводе текста в окошках и других элементах графического интерфейса пользователя (GUI).
5 Иерархия потоковых классов 5 Потоковые классы имеют довольно сложную иерархическую структуру. Операция извлечения >> является методом класса istream, операция вставки >). Класс ostream содержит функции: put(), write() и перегружаемую операцию вставки (
6 Иерархия потоковых классов 6
7 Класс ios 7 ios является дедушкой всех потоковых классов и обладает большинством особенностей, без которых работа с потоками была бы невозможна. Три его главных направления это флаги форматирования, флаги ошибок и режим работы с файлами.
8 Класс ios. Флаги форматирования 8
9 9 Есть несколько способов установки флагов форматирования, для каждого свои. Так как они являются компонентами класса ios, обычно к ним обращаются посредством написания имени класса и оператора явного задания (например, ios::skipws). Все без исключения флаги могут быть выставлены с помощью методов setf() и unsetf(). Примеры: cout.setf(ios::left); // выравнивание текста по левому краю cout
10 Класс ios. Манипуляторы 10 Манипуляторы это инструкции форматирования, которые вставляются прямо в поток. Например endl, который посылает символ разделителя строк в поток и сбрасывает буфер.
11 Класс ios. Манипуляторы 11 Следует иметь в виду, что манипуляторы действуют только на те данные, которые следуют за ними в потоке, а не на те, которые находятся перед ними. На то он и поток.
12 Класс ios. Функции 12 Класс ios содержит набор функций, с помощью которых можно выставлять флаги форматирования и выполнять некоторые другие действия. Эти функции вызываются для нужных потоковых объектов обычным способом через точку. Например: cout.width(14); cout.fill('*');
13 Класс istream 13
14 Класс istream 14
15 Класс istream 15 Нам уже встречались некоторые из этих функций, например get(). Большинство из них рассчитаны на работу с объектом cin, обычно представляющим собой поток данных, вводимых с клавиатуры. Последние четыре функции предназначены только для работы с дисковыми файлами.
16 Класс ostream 16 Класс ostream предназначен для вывода (вставки в поток) данных. Как и в предыдущем случае, последние четыре функции работают только с файлами.
17 Классы iostream и _withassign 17 Класс iostream является порожденным по отношению к istream и ostream. Его единственное предназначение выступать в качестве базового класса для других специфических классов вида iostream_withassign. У него нет собственных методов, кроме конструктора и деструктора. Его порожденные классы могут осуществлять как ввод, так и вывод данных. Существуют три класса вида _withassign: istream_withassign наследник istream; ostream_withassign наследник ostream; iostream_withassign наследник iostream. Эти классы очень похожи на своих предков. Разница лишь в том, что в них, в отличие от породивших их классов, имеются перегружаемые операции присваивания, благодаря чему их объекты могут быть скопированы.
18 Предопределенные потоковые объекты 18 Использования двух предопределенных потоковых объектов, порожденных классами вида _withassign: cin и cout мы уже знакомы. Обычно они связаны с клавиатурой и монитором соответственно. Еще двумя предопределенными объектами являются cerr и clog: cin, объект istream_withassign, используется для операций ввода с клавиатуры; cout, объект ostream_withassign, используется для операций вывода на экран монитора; cerr, объект ostream_withassign, используется для сообщений об ошибках; clog, объект ostream_withassign, используется для ведения журнала. Объект cerr часто используется для сообщений об ошибках и программной диагностики. Поток, посланный в него, немедленно выводится на экран, минуя буферизацию. Этим cerr отличается от cout. К тому же этот поток не может быть перенаправлен.
19 Ошибки потоков. Биты статуса ошибки 19
20 Ввод чисел 20 Обработка ошибки при вводе чисел. При чтении числа с клавиатуры или с диска, проверяется значение goodbit, и сообщается об ошибке, если его значение не равно true, и предоставляется возможность пользователю ввести корректное число. Задача 10-1
21 Ввод целого числа и дробного 21 Задача 10-2 Обработка ошибки при вводе чисел. При чтении числа с клавиатуры или с диска, проверяется значение goodbit, и сообщается об ошибке, если его значение не равно true, и предоставляется возможность пользователю ввести корректное число
22 Ввод целого числа и дробного (продолжение) 22 Задача 10-2
23 Ввод целого числа и дробного (окончание) 23 Задача 10-2
24 Потоковый ввод/вывод дисковых файлов 24 Большинству программ требуется сохранять данные на диске и считывать их. Работа с дисковыми файлами подразумевает наличие еще одного набора специальных классов: ifstream для ввода и ofstream для вывода. Класс fstream осуществляет и ввод, и вывод. Форматированный файловый ввод/вывод. При форматирован- ном вводе/выводе числа хранятся на диске в виде серии символов. Таким образом, число 6.02 вместо того, чтобы храниться в виде четырехбайтного значения типа float или восьмибайтного double, хранится в виде последовательности символов '6', '.', '0', '2'. Символы и строки хранятся в файлах в привычной форме.
25 Запись данных 25 Задача 10-3 Следующая программа демонстрирует запись символа, целого числа, числа типа double и двух объектов типа string в дисковый файл. Вывод на экран не производится.
26 Чтение данных 26 Задача 10-4 Прочитать файл, если он уже создан, можно с использованием объекта типа ifstream, инициализированного именем файла. Файл автоматически открывается при создании объекта. Затем данные из него можно считать с помощью оператора извлечения (>>).
27 Строки с пробелами (запись) 27 Задача 10-5 Следующая программа выводит строки с пробелами – после каждой строки нужно писать специальный символ-ограничитель и использовать функцию getline() вместо оператора извлечения. Строки стихотворения И. Бродского записаны в файл TEST.TXT
28 Строки с пробелами (чтение) 28 Задача 10-6 Следующая программа считывает строки с пробелами используя функцию getline(), результат чтения затем выводится на экран после считывания каждой строки.
29 Определение признака конца файла (EOF) 29 Итак, объекты порожденных из ios классов содержат флаги статуса ошибок, с помощью которых можно проверить результат выполнения операций. При чтении файла условие окончания файла – сигнал EOF. while(!infile.eof()) // Пока не EOF Флаги ошибок failbit и badbit тоже могут возникнуть при работе программы, мы изменим условие цикла: while(infile.good()) // Пока нет ошибок Можно также проверять поток напрямую. Запишем еще один вариант цикла while: while(infile) // Пока нет ошибок
30 Ввод символов 30 Задача 10-7 Функция put() является методом ostream, может быть использована для ввода единичных символов.
31 Вывод символов 31 Задача 10-8 а Функция get() является методом istream, может быть использована для вывода единичных символов.
32 Вывод символов 32 Задача 10-8 в Есть и другой способ читать символы из файла использовать функцию rdbuf() (она является методом класса ios).
33 Двоичный ввод/вывод 33 Задача 10-9 Массив целых чисел записывается в файл и читает- ся из него. Используются две функции write() (метод класса ofstream), read() (метод ifstream). Адрес вычислен с использованием reinterpret_cast относительно типа char*. Второй параметр – длина в байтах.
34 Оператор reinterpret_cast 34 В задаче 10-9 использует оператор reinterpret_ cast для того, чтобы буфер данных типа int выглядел для функций read() и write() как буфер типа char. is.read(reinterpret_cast (buff), MAX*sizeof(int)); reinterpret_cast изменяет тип данных в определенной области памяти, совершенно не задумываясь о том, имеет это смысл или нет. Поэтому вопрос целесообразности использования этого оператора остается целиком на совести программиста.
35 Закрытие файлов 35 До сих пор в наших примерах не нужно было вручную закрывать файлы это делалось автоматически при окончании работы с ними. Соответствующие объекты запускали деструкторы и закрывали ассоциированные файлы. Но в задаче 10-9 оба потока, входной is и выходной os, связаны с одним и тем же файлом EDATA.DAT, поэтому первый поток должен быть закрыт до того, как откроется второй. Для этого используется функция close(). Можно запускать эту функцию каждый раз при закрытии файла, не полагаясь на деструктор потока.
36 Объектный ввод/вывод 36 Так как C++ это все-таки объектно-ориентированный язык, рассмотрим, как происходит запись объектов в дисковые файлы и чтение из них.
37 Запись объекта на диск 37 Задача При записи объекта обычно используем бинарный режим. В данной программе у пользователя запрашивается информация об объекте класса person, который потом записывается в файл PERSON.DAT.
38 Чтение объекта с диска 38 Задача Для чтения используется метод read(). Из файла PERSON.DAT считывается информация объекта класса person, затем информация выводится на экран.
39 Ввод/вывод множества объектов 39 Задача В следующем примере в файл записывается произвольное число объектов. Затем они считы- ваются, и на экран выводится цели- ком содержимое файла.
40 Ввод/вывод множества объектов 40 Задача В следующем примере в файл записывается произвольное число объектов. Затем они считываются, и на экран выводится целиком содержимое файла.
41 Биты режимов 41
42 Указатели файлов 42 У каждого файлового объекта есть два ассоциированных с ним значения, называемые указатель чтения и указатель записи. Их также называют текущая позиция чтения и текущая позиция записи. Или просто текущая позиция. Функции seekg() и tellg() позволяют устанавливать и проверять текущий указатель чтения, а функции seekp() и tellp() выполнять те же действия для указателя записи.
43 Вычисление сдвига 43 Задача В следующем примере вычисляется количество записей person, по запросу выводится информация о персоне.
44 Реагирование на ошибки 44 Задача Обработка ошибок. Все дисковые опера- ции проверяются после их выполнения Программа открыва- ет выходной потоко- вый объект, записы- вает целый массив целых чисел един- ственным вызовом write() и закрывает объект. Затем откры- вает входной потоко- вый объект и считы- вает массив вызовом функции read().
45 Реагирование на ошибки 45 Задача Обработка ошибок. Все дисковые операции проверяются после их выполнения. Программа открывает выходной потоковый объект, записывает целый массив целых чисел единственным вызовом write() и закрывает объект. Затем открывает входной потоковый объект и считывает массив вызовом функции read().
46 Как классы записывают и читают сами себя 46 Статические функции Одним из способов записать за один сеанс множество объектов является употребление статической функции, которая применяется ко всему классу в целом, а не к отдельным его объектам. Такая функция действительно может записать все объекты сразу. Она обратится к массиву указателей на объекты, который можно хранить в виде статической переменной. При создании каждого объекта его указатель заносится в этот массив. Статический элемент данных также может свято хранить память о том, сколько всего объектов было создано. Статическая функция write() откроет файл, в цикле пройдет по всем ссылкам массива, записывая по очереди все объекты, и после окончания записи закроет файл.
47 Как классы записывают и читают сами себя 47 Размеры порожденных объектов Объекты, хранящиеся в памяти, имеют разные размеры. Класс employee, выступаюший как базовый для классов manager, scientist и laborer. Объекты этих трех порожденных классов имеют разные размеры, так как содержат разные объемы данных. Пусть имеется массив указателей arrар[], хранящий ссылки на объекты типа employee. Указатели могут ссылаться, таким образом, и на все три порожденных класса. При использовании виртуальных функций можно использовать выражения типа arrap[]->putdata(); Тогда будет поставлена на исполнение во время работы программы версия putdata(), соответствующая объекту, на который ссылается указатель, а не та, что соответствует базовому классу.
48 Как классы записывают и читают сами себя 48 Использование функции typeid() Можно использовать ее для определения класса объекта, подставляя имя этого класса в качестве аргумента sizeof(). Чтобы использовать typeid(), надо включить параметр компилятора RTTI. (это существенно только для компилятора Microsoft Visual C++) Наш следующий пример показывает, как все вышеописанное работает. Узнав размер объекта, мы можем использовать его в функции write() для записи в файл. К программе 10_15 добавился несложный пользовательский интерфейс. Некоторые специфичес- кие методы сделаны виртуальными, чтобы можно было пользовать- ся массивом указателей на объекты. В программу также включены некоторые приемы обнаружения ошибок. Программа демонстрирует многие приемы, которые могут быть использованы в настоящем приложении для работы с базами данных. Она также показывает реальные возможности ООП.
49 Классы записывают и читают сами себя 49 Задача Код программы - начало
50 Классы записывают и читают сами себя 50 Код программы – продолжение 1 Задача 10-15
51 Классы записывают и читают сами себя 51 Код программы – продолжение 2 Задача 10-15
52 Классы записывают и читают сами себя 52 Код программы – продолжение 3 Задача 10-15
53 Классы записывают и читают сами себя 53 Код программы – продолжение 4 Задача 10-15
54 Классы записывают и читают сами себя 54 Код программы – конец Задача 10-15
55 Как классы записывают и читают сами себя 55 Задача Код типа объекта Мы умеем определять класс объекта, находящегося в памяти, но как узнать класс объекта, если мы собираемся читать его из файла? Поэтому при записи данных на диск необходимо записывать код (перечисляемую переменную типа employee_type) прямо перед данными объекта. До начала чтения из файла надо прочитать его значение и создать объект соответствующего типа. aptr_to_obj = new aClass; // arrap[n] = new manager; И только после этого можно копировать данные из файла в этот новый объект. При корректном способе создания объекта запускается его конструктор. Это необходимо даже тогда, когда вы не определяете собственный, а используете конструктор по умолчанию. Ведь объект это нечто более глобальное, нежели просто область памяти, в которой хранятся данные. Не забывайте, что это еще и набор методов, некоторые из них вы даже не видите!
56 Как классы записывают и читают сами себя 56 Задача Взаимодействие с программой
57 Перегрузка операторов извлечения и вставки 57 Перейдем к изучению следующей темы, связанной с потоками. Данный раздел будет посвящен перегрузке операторов извлечения и вставки. Это мощный прием C++, который позволяет поддерживать ввод/вывод пользовательских типов наравне со стандартными, такими, как float и int. Например, если имеется объект класса crawdad, называющийся cd1, его можно вывести на экран простым выражением cout
58 Перегрузка cout и cin 58 Задача Приведем пример, в котором операторы извлечения и вставки для класса Distance перегружены для работы с cout и cin.
59 Перегрузка > для файлов 59 Задача Следующий пример продемонстрирует, как перегружаются операторы > в классе Distance для работы с файловым вводом/выводом.
60 Память как поток 60 Область памяти можно считать потоком и записывать в нее данные точно так же, как в файл. Это требуется, когда нужно выводить дан- ные в определенном формате (например, оставлять только два зна- ка после запятой) и одновременно использовать функцию текстового вывода, которая в качестве аргумента требует строку. Так обычно делают, вызывая функции вывода, при разработке приложений в GUI-средах, например в Windows, поскольку там этим функциям нужно передавать именно строку в качестве аргумента. Программис- ты на C, вероятно, сразу вспомнят, как они использовали sprintf() для этих целей. Семейство потоковых классов поддерживает такое форматирование данных в памяти. Для вывода в память существует специальный класс ostrstream, порожденный классом ostream. Для ввода из памяти служит класс istrstream, порожденный, соответственно, классом istream. Для объектов, которым требуется осу- ществлять одновременно ввод и вывод, создан класс strstream наследник iostream.
61 Память как поток 61 Задача Данный пример показывает, как это реально применить на практике. Создаем бу- фер данных в памяти. За- тем создайте объект ostrstream, используя этот буфер (его адрес и размер) в качестве аргументов конструктора потока. Теперь можно выводить форматированный текст в буфер, как если бы он был потоковым объектом.
62 Аргументы командной строки 62 Если вы использовали когда-нибудь старый добрый MS DOS, вам должно быть знакомо понятие аргументов командной строки, использующихся при запуске программ. Их типичное применение передача имени файла с данными в приложение. Например, вы запускаете программу редактирования текстов и хотите сразу открыть документ, с которым будете работать. Для этого вы пишете:C:\>wordproc afile.doc Здесь аргументом командной строки является afile.doc. Нам надо каким-то образом заставить программу на C++ распознавать такие обращения.
63 Аргументы командной строки 63 Задача Следующая программа, приводимая в качестве примера, считывает и выводит на экран столько аргументов командной строки, сколько вы сможете напечатать (они отделяются пробелами)
64 Список задач 10-го занятия 1. Ввод чисел 2. Ввод целого числа и дробного 3. Запись данных 4. Чтение данных 5. Строки с пробелами (запись) 6. Строки с пробелами (чтение) 7. Ввод символов 8. Вывод символов 9. Двоичный ввод/вывод 64
65 Список задач 10-го занятия 10. Запись объекта на диск 11. Чтение объекта с диска 12. Ввод/вывод множества объектов 13. Вычисление сдвига 14. Реагирование на ошибки 15. Как классы записывают и читают сами себя 16. Перегрузка cout и cin 17. Перегрузка > для файлов 18. Память как поток 19. Аргументы командной строки 65
66 Резюме 10-го занятия В этой главе мы ознакомились с иерархией потоковых классов и показали, как обрабатывать различного рода ошибки ввода/вывода. Затем мы рассмотрели некоторые варианты файлового ввода/вывода. Файлы в C++ связаны с объектами различных классов: класс ofstream используется для файлового вывода, ifstream для ввода, fstream для ввода и вывода одновременно. Методы этих или базовых классов предназначены для выполнения операций ввода/вывода. Такие операции и функции, как >, get() и read() для ввода. 66
67 Резюме 10-го занятия Функции read() и write работают с данными в двоичном режиме. Поэтому можно записывать в файлы объекты целиком, вне зависимости от типов данных, которые они содержат. Могут храниться как отдельные объекты, так и массивы и другие структуры, составленные из множества объектов. Файловый ввод/вывод может обрабатываться с использованием методов. За него могут отвечать как конкретные объекты, так и классы (с помощью статических функций). 67
68 Резюме 10-го занятия Проверка на наличие ошибок должна осуществляться после выполнения каждой файловой операции. Сам файловый объект принимает нулевое значение, если возникает какая-либо ошибка. К тому же для определения некоторых видов ошибок используются методы классов. Операции извлечения (>>) и вставки (
69 xxx.h: No such file or directory не найден заголовочный файл 'xxx.h' (неверно указано его имя, он удален или т.п.) 'xxx' undeclared (first use this function) функция или переменная 'xxx' неизвестна missing terminating " characterне закрыты кавычки " expected ; нет точки с запятой в конце оператора в предыдущей строке expected }не закрыта фигурная скобка 69 Наиболее «популярные» ошибки
70 Литература Роберт Лафоре. Объектно-ориентированное программирование в С++ 2.В. И. Шупляк. С++ Практический курс 3.В. В. Подбельский. Язык C++. Базовый курс
71 Конец 71
Еще похожие презентации в нашем архиве:
© 2024 MyShared Inc.
All rights reserved.