1 / 54

Стандартные библиотеки С++

Стандартные библиотеки С++. История возникновения. В программах на С++ часто приходится выполнять однообразные действия, для которых в языке нет стандартных средств, или такие средства не достаточно удобны.

Download Presentation

Стандартные библиотеки С++

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Стандартные библиотеки С++

  2. История возникновения • В программах на С++ часто приходится выполнять однообразные действия, для которых в языке нет стандартных средств, или такие средства не достаточно удобны. • Производители компиляторов и сред разработки предлагают средства для облегчения написания программ: • Библиотеки функций • Библиотеки классов • Часть средств была стандартизована и обычно поставляется с любым компилятором С++. • Некоторые средства приобрели такую популярность, что реализованы в современных языках как часть языка программирования.

  3. Основные вопросы • Строки • Потоковые классы • Стандартная библиотека шаблонов (STL)

  4. Строки • C++ не содержит стандартного типа данных «строка». Вместо этого он поддерживает массивы символов, завершаемые нуль-символом. • Они позволяют достичь высокой эффективности, но весьма неудобны и небезопасны в использовании, поскольку выход за границы строки не проверяется. • Тип данных string стандартной библиотеки лишен этих недостатков, но может проигрывать массивам символов в эффективности. • Основные действия со строками выполняются в нем с помощью операций и методов, а длина строки изменяется динамически в соответствии с потребностями. Строки типа string защищены от выхода информации за их границы и с ними можно работать так же, как с любым встроенным типом данных. • Для использования класса необходимо подключить к программе заголовочный файл <string>.

  5. Пример использования string #include <cstring> #include <string> #include <iostream> using namespace std; int main (){ char c1[80], c2[80], сЗ[80];// Строки с завершающим нулем string s1, s2, s3; // Присваивание строк strcpy(c1, "old string one"); strcpy(c2, cl); s1 = "new string one"; s2 = s1; // Конкатенация строк strcpy(c3, c1); strcat(c3, c2); s3 = s1 + s2; // Сравнение строк if (strcmp(c2, c3) < 0 ) …; else …; if (s2 < s3) …; else …; }

  6. Конструкторы и присваивание строк • Конструкторы: • string(); • string(const char *); • string(const char *,int n); • string(string&); • Операторы присваивания • string& operator=(const string& str); • string& operator=(const char* s); • string& operator=(char c); • Примеры: • string s1; • string s2("Вася"); • string s3(s2); • s1 = 'X'; • s1 = "Вася"; • s2 = s3;

  7. Операции Операция Действие Операция Действие = присваивание > больше + конкатенация >= больше или равно == равенство [ ] индексация != неравенство « вывод < меньше » ввод <= меньше или равно += добавление

  8. Методы • Вставка • insert(size_type pos, const string& str): • insert(size_type pos, const string& str, size_type pos2, size_type n); • insert(size_type pos, const char* s, size_type n); • Удаление • erase(size_type pos = 0, size_type n = npos); • clear(); • Выделение подстроки • string substr(size_type pos = 0, size_type n = npos); • Преобразование в массив символов • const char* c_str(); • Поиск подстрок • size_type find(const string &s, size_type pos = 0); • size_type find(char с, size_type pos = 0); • size_type rfind(const string& str, size_type pos = npos); • size_type rfind(char с, size_type pos = npos); • size_type find_first_of(char с, size_type pos = 0); • size_type find_last_of(char с, size_type pos = npos); • size_type find_first_of(const string& str, size_type pos = 0); • size_type find_last_of(const string& str, size_type pos = npos); • …

  9. Пример применения методов поиска #include <string> #include <iostream> using namespace std; int main (){ string s1("лесная королева"), s2("ле"); cout « "s1= " « s1 « endl; cout « "s2= " « s2 « endl; int i = s1.find(s2); int j = s1.rfind(s2); cout « "первое s2 в s1 " « i « endl; cout « "последнее s2 в s1 " « j « endl; cout « "первое 'о' в s1 " « s1.find('o') « endl; cout « "последнее 'о' в s1 " « s1.rfind('o') « endl; cout « "первое в s1 " « s1.find_first_of(«абвгде») « endl; cout « "последнее в s1 " « s1.find_last_of(«абвгде») « endl; } Результат работы программы: sl= лесная королева s2= ле первое s2 в s1 0 последнее s2 в s1 11 первое 'о' в s1 8 последнее 'о' в s1 10 первое в s1 1 последнее в s1 14

  10. Получение характеристик строк • size_type size() const; // Количество элементов строки • size_type length() const; // Количество элементов строки • size_type max_size() const; // Максимальная длина строки • size_type capacity() const; // Объем памяти, занимаемый строкой • bool empty()const; // Истина, если строка пустая

  11. Потоковые классы • Поток — это абстрактное понятие, относящееся к любому переносу данных от источника к приемнику. • Потоки C++ обеспечивают • надежную работу как со стандартными, так и с определенными пользователем типами данных, • единообразный и понятный синтаксис. • Чтение данных из потока называется извлечением, вывод в поток — помещением, или включением. • Поток определяется как последовательность байтов и не зависит от конкретного устройства, с которым производится обмен (оперативная память, файл на диске, клавиатура или принтер). • По направлению обмена потоки можно разделить на • входные (данные вводятся в память), • выходные (данные выводятся из памяти) • двунаправленные (допускающие как извлечение, так и включение). • По виду устройств, с которыми работает поток: • Стандартные (для передачи данных от клавиатуры и на экран дисплея), • Файловые (для обмена информацией с файлами на внешних носителях данных ), • Строковые (для работы с массивами символов в оперативной памяти).

  12. Иерархия классов для поддержки потоков • Базовые классы: • ios – содержит общие для ввода и вывода поля и методы, • streambuf обеспечивает буферизацию потоков и их взаимодействие с физическими устройствами. • От этих классов наследуется класс istream для входных потоков и ostream — для выходных. • Два последних класса являются базовыми для класса iostream, реализующего двунаправленные потоки. • Ниже в иерархии располагаются файловые и строковые потоки: • istringstream – класс входных строковых потоков; • ostringstream – класс выходных строковых потоков; • iostringstream – класс двунаправленных строковых потоков; • ifstream — класс входных файловых потоков; • ofstream — класс выходных файловых потоков; • fstream — класс двунаправленных файловых потоков.

  13. Основные заголовочные файлы с описаниями классов потоков • #include <iostream> – стандартные объекты и операции с потоками ввода/вывода; • #include <fstream> – потоки ввода/вывода в файлы; • #include <sstream> – потоки ввода/вывода в строки; • Необходимо использовать пространство имен std • using namespace std; • Недостаток потоков – снижение быстродействия, для некоторых компиляторов может быть весьма значительным.

  14. Стандартные потоки • Заголовочный файл <iostream> содержит, кроме описания классов для ввода/вывода, четыре предопределенных объекта: В классах istream и ostream операции извлечения из потока “»” и помещения в поток “«” определены путем перегрузки операций сдвига.

  15. Пример использования стандартных потоков #include <iostream.h> int main(){ inti; cin » i; cout « "Вы ввели " « i; return 0; } • Операции извлечения и чтения в качестве результата своего выполнения формируют ссылку на объект типа istream для извлечения и ссылку на ostream — для чтения.

  16. Особенности ввода • Помещение в буфер ввода происходит после нажатия клавиши перевода строки, после чего из буфера выполняется операция извлечения из потока. • Это дает возможность исправлять введенные символы до того, как нажата клавиша Enter. • Привводе строк извлечение происходит до ближайшего пробела (вместо него в строку заносится нуль-символ): char str1[100], str2[100]; cin » str1 » str2; • Если с клавиатуры вводится строка "раз два три четыре пять", переменные str1 и str2 примут значения "раз" и "два" соответственно, а остаток строки воспринят не будет . • При необходимости ввести из входного потока строку целиком (до символа '\n') пользуются методами get или getline.

  17. Форматирование вывода • В потоковых классах форматирование выполняется тремя способами: • c помощью флагов; • c помощью манипуляторов; • c помощью форматирующих методов.

  18. Флаги форматирования • Для управления флагами в классе ios есть методы flags, setf и unsetf.

  19. Форматирующие методы • int ios::width() - возвращает значение ширины поля вывода; • int ios::width(int) - устанавливает ширину поля вывода в соответствии созначением параметра; • int ios::precision()—возвращает значение точности представления при выводе вещественных чисел; • int ios:: precision(int) — устанавливает значение точности представления при выводе вещественных чисел, возвращает старое значение точности; • char ios::fill() — возвращает текущий символ заполнения; • char ios::fill(char) — устанавливает значение текущего символа заполнения, возвращает старое значение символа.

  20. Пример использования флагов и методов форматирования #include <iostream.h> int main(){ long a = 1000, b = 077; cout.width(7); cout.setf(ios::hex | ios::showbase | ios::uppercase); cout «a; cout.width(7); cout« b « endl; double d = 0.12, с = 1.3е-4; cout.setf(ios::left); cout« d « endl; cout« c; return 0; } • В результате работы программы в первой строке будут прописными буквами выведены переменные а и b в шестнадцатеричном представлении, под каждую из них отводится по 7 позиций (функция width действует только на одно выводимое значение, поэтому ее вызов требуется повторить дважды). Значения переменных d и сприжаты к левому краю поля: 0ХЗЕ8 0X3F 0.12 0.00013

  21. Манипуляторы • Манипуляторами называются функции, которые можно включать в цепочку операций помещения и извлечения для форматирования данных. • Манипуляторы делятся на простые, не требующие указания аргументов, и параметризованные. • Пользоваться манипуляторами более удобно, чем методами установки флагов форматирования.

  22. Простые манипуляторы • dec— устанавливает при вводе и выводе флаг десятичной системы счисления; • oct— устанавливает при вводе и выводе флаг восьмеричной системы счисления; • hex — устанавливает при вводе и выводе флаг шестнадцатеричной системы счисления; • ws— устанавливает при вводе извлечение пробельных символов; • endl— при выводе включает в поток символ новой строки и выгружает буфер; • ends — при выводе включает в поток нулевой символ; • fIush— при выводе выгружает буфер. • Например: : cout« 13 « hex « ' ' « 13 « oct« ' ' « 13 «endl; Если другие значения флагов установлены но умолчанию, будет выведено: 13 d 15

  23. Параметризованные манипуляторы • Для использования требуется подключить к программе заголовочный файл <iomanip>. • setbase(int n)— задает основание системы счисления (n = 8, 16, 10 или 0).0 является основанием по умолчанию (десятичное, кроме случаев, когда вводятся 8- или 16-ричные числа); • resetiosflags(long)— сбрасывает флаги состояния потока, биты которых установлены в параметре; • setiosflags(long) — устанавливает флаги состояния потока, биты которых в параметре равны 1; • setfill(int) — устанавливает символ-заполнитель с кодом, равным значению параметра; • precision(int)— устанавливает максимальное количество цифр в дробной части для вещественных чисел в форме с фиксированной точкой (флаг fixed) или общее количество значащих цифр для чисел в форме с мантиссой и порядком (флаг scientific); • setw(int)— устанавливает минимальную ширину поля вывода,

  24. Пример использования параметризированных манипуляторов #include <iostream.h> #include <iomanip.h> intmain(){ double d[] = {1.234, -12.34567, 123.456789,-1.234., 0.00001}; cout« setfill('.') « setprecision(4) « setiosflags(ios: :showpoint | ios::fixed); for (inti= 0: i< 5; i++) cout« setw(12) « d[i] « endl; return 0; } Результат работы программы: ......1.2340 ....-12.3457 ....123.4568 .....-1.2340 ......0.0000

  25. Методы обмена с потоками (1) • В потоковых классах наряду с операциями извлечения » и включения « определены методы для неформатированного чтения и записи в поток (при этом преобразования данных не выполняются). • gcount()— возвращает количество символов, считанных с помощью последней функции неформатированного ввода; • get()– возвращает код извлеченного из потока символаили EOF; • get(c)– возвращает ссылку на поток, из которого выполнялось чтение, и записывает извлеченный символ в с; • get(buf,num,lim = ‘\n’)– считывает num-1 символов (или пока не встретитсясимвол lim) и копирует их в символьную строкуbuf. Вместо символа limв строку записывается признак конца строки ('\0'). Символ limостается в потоке. Возвращает ссылку на текущий поток; • getline(buf,num,lim = ‘\n’)– аналогична функции get, но копирует в bufи символ lim; • ignore(num = 1, lim = EOF)– считывает и пропускает символы до тех пор, покане будет прочитано numсимволов или не встретитсяразделитель, заданный параметром lim. Возвращаетссылку на текущий поток; • peek()– возвращает следующий символ без удаления его изпотока или EOF, если достигнут конец файла; • putback(c)– помещает в поток символ с, который становится текущим при извлечении из потока; • read(buf,num)– считывает numсимволов (или все символы до конца файла, если их меньше num) в символьный массив bufи возвращает ссылку на текущий поток; • readsome(buf,num)– считывает numсимволов (или все символы до конца файла, если их меньше num) в символьный массив bufи возвращает количество считанных символов.

  26. Методы обмена с потоками (2) • flush()– записывает содержимое потока вывода на физическое устройство; • put(c)– выводит в поток символ с и возвращает ссылку на поток; • seekg (pos)- устанавливает текущую позицию записи в значение pos; • seekg (offs, org)— перемещает текущую позицию записи на offs байтов, считая от одной из трех позиций, определяемых параметром org: ios:: beg (от начала файла), ios::cur (от текущей позиции) или ios: :end (от конца файла); • tellg()– возвращает текущую позицию записи потока; • write(buf,num)– записывает в поток numсимволов из массива bufи возвращает ссылку на поток.

  27. Пример чтения строки #include "iostream.h" int main(){ const int N = 20,Len = 100; char str [N] [Len]; int i = 0; while (cin.getline(str[i], Len, '\n') && i<N){ // … i++; } return 0; }

  28. Файловые потоки • По способу доступа файлы можно разделить на • последовательные (чтение и запись производятся с начала байт за байтом) • с произвольным доступом(допускающие чтение и запись в указанную позицию) • Стандартная библиотека содержит три класса для работы с файлами: • ifstream— класс входных файловых потоков; • ofstream—класс выходных файловых потоков; • fstream— класс двунаправленных файловых потоков. • Эти классы являются производными от классов istream, ostreamи iostreamсоответственно, поэтому они наследуют перегруженные операции « и », флаги форматирования, манипуляторы, методы, состояние потоков и т. д. • Использование файлов в программе предполагает следующие операции: • создание потока; • открытие потока и связывание его с файлом; • обмен (ввод/вывод); . • уничтожение потока; • закрытие файла.

  29. Конструкторы файловых потоков • Каждый класс файловых потоков содержит конструкторы, с помощью которых можно создавать объекты этих классов различными способами. • Конструкторы без параметров создают объект соответствующего класса, не связывая его с файлом: • ifstream(); • ofstream(); • fstream(); • Конструкторы с параметрами создают объект соответствующего класса, открывают файл с указанным именем и связывают файл с объектом: • ifstream(const char *name, int mode = ios::in); • ofstream(const char *name, int mode = ios::out | ios::trunc); • fstream(const char *name, int mode = ios::out | ios::in); • Другой способ открыть файл – использовать метод open, с параметрами как у конструктора.

  30. Режимы открытия файлов • Вторым параметром конструктора является режим открытия файла. Если установленное по умолчанию значение не устраивает программиста, можно указать другое, составив его из битовых масок, определенных в классе ios: enum open_mode{ in= 0x01, // Открыть для чтения out= 0x02, // Открыть для записи ate= 0x04, // Установить указатель на конец файла app= 0x08, // Открыть для добавления в конец trunc= 0x10, // Если файл существует, удалить nocreate= 0x20, // Если файл не существует, выдать ошибку noreplace= 0x40, // Если файл существует, выдать ошибку binary= 0x80 // Открыть в двоичном режиме };

  31. Строковые потоки • Строковые потоки позволяют считывать и записывать информацию из областей оперативной памяти так же, как из файла, с консоли или на дисплей. • В стандартной библиотеке определено три класса строковых потоков: • istringstream — входные строковые потоки; • ostringstream — выходные строковые потоки; • stringstream — двунаправленные строковые потоки. • Эти классы определяются в заголовочном файле <sstream> и являются производными от классов istream, ostream и iostream соответственно, поэтому они наследуют перегруженные операции « и », флаги форматирования, манипуляторы, методы, состояние потоков и т. д.

  32. Создание строковых потоков • Участки памяти, с которыми выполняются операции извлечения и включения, по стандарту определяются как строки C++ (класс string). • Строковые потоки создаются и связываются с этими участками памяти с помощью конструкторов: • explicitistringstream(int mode = ios::in); • explicit istringstream(const string& name, int mode = ios::in); • explicit ostringstream(int mode = ios::out); • explicit ostringstream(const string& name, int mode = ios::out); • explicit stringstream(int mode = ios::in | ios::out); • explicit stringstream(const string& name, int mode = ios::in | ios::out); • explicit – означает, что конструктор может быть вызван только явным образом.

  33. Пример использования строкового потока #include <sstream> #include <string> #include <iostream> #include <ctime> using namespace std; string message( int i){ ostringstream os; time_t t; time(&t); os « " time: " « ctime(&t) « " number: " « i « endl; return os.str(); } int main(){ cout << message(22); return 0; }

  34. Потоки и типы, определенные пользователем • Для ввода и вывода в потоках используются перегруженные для всех стандартных типов операции чтения и извлечения « и ». При этом выбор конкретной операции определяется типом фактических параметров. • Для того чтобы вводить и выводить величины типов, определенных пользователем, требуется перегрузить эти операции. • Это бинарные операции, левым операндом которых является объект-поток, а правым — объект, который требуется извлечь или поместить в поток. • Возвращаемое значение должно быть ссылкой на поток, чтобы можно было организовывать цепочки операций, как и в случае стандартных типов

  35. Пример использования потоков с типом пользователя сlass MyClass{ intx; float y; public: MyClass(int nx = 1, float ny = 0.01){x = nx; у = ny;} friend ostream& operator « (ostream& out, MyClass& C) { return out « "x = " « C.x « " у = " « С.y; } friend istreams operator » (istream& in,MyClass& C) { cout « "Введите x: “; in » C.x; cout « "Введите у: “; in » С.у; return in; } }; int main(){ MyClass C; cout « С « endl; MyClass C1(100, 100); cout « C1 « endl; MyClass C2; cin » C2; cout « C2 « endl; return 0; }

  36. Стандартная библиотека шаблонов (STL) • Контейнеры • Итераторы • Алгоритмы

  37. Контейнерные классы • Контейнеры – структуры данных, предназначенные для хранения набора однотипных объектов • Примерами контейнеров могут служить массивы, линейные списки или стеки. • Для каждого типа контейнера определены методы для работы с его элементами, не зависящие от конкретного типа данных, которые хранятся в контейнере, поэтому один и тот же вид контейнера можно использовать для хранения данных различных типов. • Использование контейнеров позволяет значительно повысить надежность программ, их переносимость и универсальность, а также уменьшить сроки их разработки.

  38. Виды контейнеров • Последовательные • обеспечивают хранение конечного количества однотипных величин в виде непрерывной последовательности. • К ним относятся • векторы (vector), • двусторонние очереди (deque), • списки (list), • стеки (stack), • очереди (queue), • очереди с приоритетами (priority_queue). • Ассоциативные • обеспечивают быстрый доступ к данным по ключу. • построены на основе сбалансированных деревьев. • Существует пять типов ассоциативных контейнеров: • словари (mар), • словари с дубликатами (multimap), • множества (set), • множества с дубликатами (multiset); • битовые множества (bitset).

  39. Виды контейнеров

  40. Последовательные контейнеры Вектор — это структура, эффективно реализующая произвольный доступ к элементам, добавление в конец и удаление из конца. Двусторонняя очередь эффективно реализует произвольный доступ к элементам, добавление в оба конца и удаление из обоих концов. Список эффективно реализует вставку и удаление элементов в произвольное место, но не имеет произвольного доступа к своим элементам.

  41. Пример работы с вектором #include <fstream> #include <vector> using namespace std; int main(){ ifstream in ("inpnum.txt"); vector<int> v; int x; while ( in » x && !in.eof()) v.push_back(x); for (vector<int>::iterator i = v.begin(); i != v.end(); ++i) cout « *i « " "; }

  42. Деки • Различие дека и вектора в том, что динамический массив дека открыт с двух концов.

  43. Операции с деками

  44. Списки • Элементы контейнера list библиотеки STL объединены в двусвязный список. • Для использования списков необходимо подключить заголовочный файл <list> • Список не поддерживает произвольный доступ к элементам • В списках не определён оператор индексирования ([]) и функция at() • Вставка и удаление элементов в любой позиции выполняются быстро. • После вставки и удаления элементов указатели на др. элементы остаются действительными • Список не может оказаться в промежуточном состоянии (операция неделима) • Списки не перераспределяют память

  45. #include "stdafx.h" #include <stdlib.h> #include <iostream> #include <list> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { list<int> v; for(int i=0;i<10;i++) v.push_back(rand()); cout<< “В списке ” << v.size() << “элементов” <<endl; cout << endl <<endl; return 0; }

  46. Словари и словари с дубликатами • Элементами являются пары «ключ/значение». • Сортировка элементов проводится по ключу. #include <map> template <class Key, class T, class Compare = less<Key>, class Allocator=allocator<pair<const Key,T> > > • Первый аргумент шаблона определяет тип ключа, второй- тип значения. • Необязательный третий аргумент – критерий сортировки. • Необязательный четвёртый параметр – модель памяти.

  47. Критерии сортировки Критерий сортировки определяется тремя свойствами: • Ассиметричность: • Для оператора <: если выражение x<y истинно, то выражение y<x ложно. • Для предиката op(): если выражение op(x,y) истинно, то выражение op(y,x) ложно. 2. Транзитивность: • Для оператора <: если выражения x<y и y<z истинны, то выражение x<z истинно. • Для предиката op(x,y) и op(y,z) истинны, то выражение op(x,z) истинно. 3. Иррефлексивность: • Для оператора <: выражение x<x всегда ложно. • Для предиката op(): выражение op(x,x) всегда ложно. Для проверки равества используестся следующее правило: «Два элемента равны, если ни один из них не меньше другого (или если ложны оба выражения op(x,y) и op(y,x).

  48. #include <map> #include <string> #include <iostream> using namespace std; int main() { map<int,string> m1; m1[1] ="Иванов"; map<string,int> m2; m2["Петров"] = 5; int x = m2[“Сидоров”]; cout << "m1[1]=" << m1[1] << endl; cout << "m2[\"Петров\"]=" << m2["Петров"] << endl; return 0; }

  49. Множества и множества с дубликатами

  50. Внутренняя структура множеств

More Related