МЕНЮ


Фестивали и конкурсы
Семинары
Издания
О МОДНТ
Приглашения
Поздравляем

НАУЧНЫЕ РАБОТЫ


  • Инновационный менеджмент
  • Инвестиции
  • ИГП
  • Земельное право
  • Журналистика
  • Жилищное право
  • Радиоэлектроника
  • Психология
  • Программирование и комп-ры
  • Предпринимательство
  • Право
  • Политология
  • Полиграфия
  • Педагогика
  • Оккультизм и уфология
  • Начертательная геометрия
  • Бухучет управленчучет
  • Биология
  • Бизнес-план
  • Безопасность жизнедеятельности
  • Банковское дело
  • АХД экпред финансы предприятий
  • Аудит
  • Ветеринария
  • Валютные отношения
  • Бухгалтерский учет и аудит
  • Ботаника и сельское хозяйство
  • Биржевое дело
  • Банковское дело
  • Астрономия
  • Архитектура
  • Арбитражный процесс
  • Безопасность жизнедеятельности
  • Административное право
  • Авиация и космонавтика
  • Кулинария
  • Наука и техника
  • Криминология
  • Криминалистика
  • Косметология
  • Коммуникации и связь
  • Кибернетика
  • Исторические личности
  • Информатика
  • Инвестиции
  • по Зоология
  • Журналистика
  • Карта сайта
  • Лекции по C++

    f.write((const unsigned char*) &len, sizeof(len));

    f.write((const unsigned char*) buff, len);

    f.close();

    В этом примере открывается файл CALC.DAT, записывается целое,

    содержащее число байт в строке и записывается сама строка перед тем, как

    файл закрывается.

    Функция read считывает некоторое количество байт из входного потока.

    Эта функция может считывать любую переменную или экземпляр из потока.

    Функция-элемент read

    Прототип перегруженной функции-элемента read:

    ostream& read(char* buff, int num);

    ostream& read(signed char* buff, int num);

    ostream& read(unsigned char* buff, int num);

    Параметр buff - это указатель на буфер, который принимает данные из

    входного потока. Параметр num указывает число считываемых из потока байт.

    Пример 5.

    const MAX = 80;

    char buff [MAX+1];

    int len;

    fstream f;

    f.open("CALC.DAT", ios::in | ios::binary);

    f.read((unsigned char*) &len, sizeof(len));

    f.read((unsigned char*) buff, len);

    f.close();

    В этом примере считывается информация, записанная в предыдущем

    примере.

    Рассмотрим пример, выполняющий последовательный двоичный потоковый

    ввод/вывод. В листинге 10.2 представлен исходный код программы ARRAY.CPP.

    Эта программа объявляет класс, который моделирует численный динамический

    массив. Операции ввода/вывода позволяют программе читать и писать как

    отдельные элементы массива, так и целый массив в двоичный файл. Эта

    программа создает массивы arr1, arr2 и аrrЗ, а затем выполняет следующие

    задачи:

    - Присваивает значения элементам массива arr1. (Этот массив имеет 10

    элементов).

    - Присваивает значения элементам массива аrrЗ. (Этот массив имеет 20

    элементов).

    - Отображает значения массива arr1.

    - Записывает элементы массива arr1 в файл ARRAY1.DAT (по одному за

    операцию).

    - Читает элементы массива arr1 из этого файла в массив arr2 (по

    одному за операцию). (Массив arr2 имеет 10 элементов, то есть он

    одного размера с массивом arr1).

    - Отображает элементы массива arr2.

    - Отображает элементы массива аrrЗ.

    - Записывает элементы массива аrrЗ в файл ARRAY3.DAT, все сразу.

    - Читает (все сразу) данные из файла ARRAY3.DAT и сохраняет их в

    массиве arr1.

    - Отображает значения массива arr1. (Выход показывает, что массив

    arr1 имеет тот же размер, что и массив arr3).

    Листинг 10.2. Исходный код программы ARRAY.CPP

    // C++ демонстрация последовательного двоичного

    // ввода/вывода

    Программа листинга 10.2 объявляет версию класса Array, который похож

    на приводимый в главе 8 в листинге 8.2. Основное отличие в том, что здесь

    мы использовали operator[ ] для замены и функции store, и recall. Эта

    операция проверяет правильность указания индекса и возвращает значение в

    badIndex, если аргумент выходит за диапазон массива. В дополнение к

    operator[ ] мы добавили функции-элементы writeElem, readElem, writeArray и

    readArray для выполнения последовательного двоичного файлового

    ввода/вывода. Мы также добавили функции resize и getPrt как вспомогательные

    функции соответственно для изменения размера массива и для возвращения

    указателя на соответствующий элемент массива.

    Обратите внимание также на копирующий конструктор в строке 29, и

    особенно на то, что он действительно ничего не определяет. Это - прием,

    который может быть использован для защиты других функций или классов от их

    автоматического копирования, когда вы знаете, что это плохо (в этом случае

    потому, что используются динамические данные, содержимое которых необходимо

    копировать).

    Функция writeElem, определенная в строках с 43 по 49, записывает

    одиночные элементы массива в выходной поток. Параметр os представляет

    выходной поток. Параметр index определяет элемент массива для записи.

    Функция writeElem возвращает true, если индекс правильный и если операция

    по выводу осуществляется без ошибок. После того, как writeElem записывает

    элемент массива, внутренний указатель потока продвигается в следующее

    положение.

    Функция readElem, определяемая в строках с 51 по 57, считывает

    одиночный элемент массива из входного потока. Параметр Is представляет

    входной поток. Параметр index определяет индекс элемента массива для

    чтения. Эта функция возвращает true, если индекс массива правильный и если

    операция по вводу осуществляется без ошибок. После того, как readElem

    считывает элемент массива, внутренний указатель потока продвигается в

    следующее положение.

    Функции writeElem и readElem позволяют экземпляру класса

    соответственно писать и читать элементы данных из различных потоков.

    Функция writeArray, определенная в строках с 59 по 69, записывает все

    элементы массива в двоичный файл. Параметр filename определяет имя

    выходного файла. Функция открывает выходной поток и записывает значение

    элемента класса size, а затем и элементы динамического массива. Функция

    writeArray возвращает true, если массив в поток записан успешно. Иначе она

    возвращает false. Эта функция открывает локальный выходной поток, используя

    потоковую функцию open и передавая ей имя файла и режим ввода/вывода. Режим

    ввода/вывода представляет собой выражение ios::out|ios::binary, которое

    определяет, что поток открывается только для вывода двоичных записей. Эта

    функция дважды вызывает потоковую функцию write - первый раз для записи

    компонента класса size, второй - для записи элементов динамического

    массива.

    Функция readArray, определенная в строках с 71 по 83, читает все

    элементы массива из двоичного файла. Параметр filename определяет имя

    входного файла. Функция открывает входной поток и считывает значение

    компонента класса size, а затем считывает элементы динамического массива.

    Функция readArray возвращает true, если она успешно считывает массив из

    потока. В противном случае, возвращается false. Функция открывает локальный

    входной поток, используя потоковую функцию open и передавая ей имя файла и

    аргументы режима ввода/вывода. Аргумент режима ввода/вывода - это выражение

    ios::in | ios::binary, которое определяет, что поток открыт только для

    двоичного ввода. Функция делает два вызова потоковой функции read, первый -

    для чтения элемента класса size, и второй - для чтения элементов

    динамического массива. Другим свойством функции readArray является то, что

    она изменяет размер экземпляра класса Array для настройки его в

    соответствии с данными двоичного файла, вызывая функцию-элемент resize. Это

    означает, что динамический массив, который доступен посредством экземпляра

    класса, может либо уменьшаться, либо расширяться в зависимости от размера

    массива, сохраняемого в файле.

    Функция-элемент resize, которая начинается в строке 65, на самом деле

    очень простая. Она проверяет, является ли требуемый размер тем же, что и

    установленный ранее. Если нет, то память, зарезервированная функцией

    dataPtr, освобождается, а затем создается новая область памяти,

    соответствующая новому размеру. Этот новый размер присваивается компоненту

    класса size.

    Функция dispArray чаще всего является функцией-элементом, но я решил

    сделать ее здесь обычной функцией, чтобы лучше показать, как использование

    функции operator[ ] позволяет тем, кто работает с классом Array, обращаться

    к нему таким же способом, какой они применяют к элементам стандартного

    массива. В этом случае есть простой цикл for, который выполняется для

    каждого элемента arr и отображает его содержимое.

    Наконец, мы подходим к функции main (строка 104). Обычно она в

    основном

    только запускает функции, которые уже были созданы, для выполнения

    следующих задач:

    - Объявляет (строка 108) три экземпляра класса Array с именами arr1,

    arr2 и аrr3. (Первые два экземпляра имеют тот же самый размер

    динамического массива, заданный константой SIZE1, в то время как

    аrr3 имеет больший размер, определенный константой SIZE2).

    - Объявляет (строка 111) файловый поток f и открывает его (используя

    конструктор потока) для доступа к файлу ARRAY1.DAT в двоичном

    режиме.

    - Использует циклы for (строки с 114 по 116), чтобы произвольно

    присвоить значения экземплярам arr1 и аrr3.

    - Отображает элементы экземпляра arr1 (строка 119).

    - Записывает элементы массива arr1 в выходной файловый поток f,

    используя цикл for (строка 122) для вызова функции-компонента

    writeElem с выходным файловым потоком f и переменной цикла i.

    - Закрывает файловый поток f, вызывая функцию-элемент close этого

    потока.

    - Открывает (строка 127) файловый поток f для доступа к файлу

    ARRAY1.DAT. (На это раз сообщение open определяет режим двоичного

    ввода)

    - Считывает элементы в arr2 (которому до сих пор не присваивались

    никакие значения) из входного файлового потока f, используя цикл

    for (строка 128).

    - Закрывает входной поток (строка 130). D Отображает элементы

    экземпляров arr2 и аrr3 (строки 132 и 133).

    - Записывает все содержимое аrr3, вызывая функцию-компонент

    writeArray. (Функция writeArray имеет аргумент имени файла

    ARRAY3.DAT).

    - Считывает массив файла ARRAY3.DAT в экземпляр arr1, вызывая функцию-

    компонент readArray и передавая ей в качестве аргумента имени файла

    ARRAY3.DAT.

    - Отображает новые элементы экземпляра arr1.

    Файловый ввод/вывод с прямым доступом

    Файловые операции ввода/вывода прямого доступа также используют

    потоковые функции-элементы read и write, представленные в предыдущем

    разделе. Stream-библиотека имеет ряд функций, позволяющих вам передвигать

    указатель потока в любое необходимое положение. Функция-элемент seekg -

    одна из таких функций.

    Функция-элемент seekg

    Прототип для перегруженной функции-компонента seekg:

    istream& seekg(long pos);

    istream& seekg(long offset, seek_dir dir);

    Параметр pos в первой версии определяет абсолютное положение байта в

    потоке. Во второй версии параметр offset определяет относительное смещение,

    в зависимости от аргумента dir. Аргументы для последнего параметра:

    ios::beg С начала файла

    ios::cur С текущей позиции файла

    ios::end С конца файла

    Пример

    const BLOCK SIZE = 80

    char buff[BLOCK_SIZE] = "Hello World!";

    f.open("CALC.DAT", ios::in | ios::out | ios::binary);

    f.seekg(3 * BLOCK_SIZE); // продвинутся к блоку 4

    f.read((const unsigned char*)buff, BLOCK_SIZE);

    cout < buff < endl;

    fclose ();

    Виртуальный массив - это базирующийся на диске массив, который

    сохраняет строки фиксированного размера на диске. Вы можете рассматривать

    его как обычный массив, который вместо сохранения своих элементов в памяти

    записывает их в дисковый файл.

    Рассмотрим пример файлового ввода/вывода прямого доступа. В листинге

    10.3 приведен исходный код программы VIRTUAL.CPP и реализует виртуальный

    массив. Программа выполняет следующие задачи:

    - Использует внутренний список имен для создания объекта виртуального

    массива.

    - Отображает элементы неупорядоченного объекта виртуального массива.

    - Сортирует элементы объекта виртуального массива.

    - Отображает элементы сортированного объекта виртуального массива.

    -

    Листинг 10.3. Исходный код прогшраммы VIRTUAL.CPP

    // C++ демонстрация файлового ввода/вывода прямого доступа

    Программа листинга 10.3 объявляет класс VmArray. Этот класс моделирует

    динамический базирующийся на диске массив, который сохраняет все его

    элементы в двоичном файле прямого доступа. Заметьте, что в этом классе

    объявлен экземпляр класса fstream и что не существует указателя на

    динамический массив. Класс объявляет конструктор, деструктор и ряд функций-

    компонентов.

    Конструктор класса имеет два параметра: Size и filename. Параметр Size

    задает размер виртуального массива. Параметр filename именует двоичный

    файл, который сохраняет элементы экземпляров класса. Конструктор открывает

    поток f, используя потоковую функцию open и передавая ей в качестве

    аргументов filename и выражение для режима работы с файлом ios::in |

    ios::out | ios::binary.

    Это выражение указывает, что поток открывается для двоичного

    ввода/вывода (то есть режима прямого доступа). Если конструктор успешно

    открывает файловый поток, он заполняет файл пустыми строками. Деструктор

    класса выполняет простую задачу закрытия файлового потока f.

    Функции setElem и getElem поддерживают прямой доступ к элементам

    массива. Эти функции используют потоковую функцию seekg, чтобы

    устанавливать указатель потока на соответствующий элемент массива. Затем

    функция setElem вызывает потоковую функцию write для сохранения элемента

    массива (передаваемый параметром str). Напротив, функция getElem называет

    потоковую функцию read, чтобы получить элемент массива (возвращаемый через

    аргумент str). Обе функции возвращают результат типа bad, который указывает

    на успешность операции ввода/вывода.

    Класс VmArray также объявляет функцию BubbleSort для сортировки

    элементов виртуального массива. Эта функция использует функции-элементы

    getElem и setElem для доступа и свопинга элементов массива. Затем, наконец,

    запускается последняя функция-элемент display для элементов виртуального

    массива, которая посылает их на экран. Функция main выполняет следующие

    задачи:

    - Объявляет экземпляр arr класса VmArray. (Этот экземпляр сохраняет

    10 строк в двоичном файле ARR.DAT)

    - Присваивает случайное значение элементам экземпляра аот, используя

    цикл for (строки 97 и 98).

    - Отображает несортированные элементы экземпляра arr, вызывая функцию-

    элемент display.

    - Сортирует массив, вызывая функцию BubbleSort.

    - Отображает сортированные элементы экземпляра arr.

    Заключение

    Сегодняшний урок представил краткое введение в библиотеку ввода/вывода

    C++ и вынес на обсуждение следующие вопросы:

    - Общие функции ввода/вывода, включая open, close, good, fail и

    оператор !.

    - Функция open открывает файловый поток ввода/вывода и поддерживает

    попеременный и множественный режимы ввода/вывода. Функция close

    закрывает файловый поток. Функции good и fail индицируют успешную

    или ошибочную, соответственно, потоковую операцию ввода/вывода.

    - C++ позволяет выполнять последовательный потоковый ввод/вывод для

    текста с использованием операций < и >, так же как и при помощи

    потоковой функции getline. Операция < позволяет записать символы и

    строки (а также и другие предопределенные типы данных). Операция >

    применяется для

    - получения символов. Функция getline позволяет вашему приложению

    считывать строки с клавиатуры или из текстового файла.

    - Последовательный потоковый ввод/вывод двоичных данных использует

    потоковые функции write или read для записи или считывания данных

    из переменных любого типа.

    - Потоковый ввод/вывод прямого доступа для двоичных данных использует

    функцию seekg в объединении с функциями read и write. Функция seekg

    позволяет вам передвигать потоковый указатель либо в абсолютное,

    либо в относительное положение в потоке.

    Вопросы и ответы

    Как можно эмулировать прямой доступ к строкам в текстовом файле?

    Сначала считывайте строки из файла как текст, получайте длину строк

    (плюс два символа для конца каждой строки) и сохраняйте накапливаемую длину

    в специальном массиве. (Назовите его, например, lineIndex) Этот массив

    сохраняет позицию байта, где начинается каждая строка. Последний элемент

    массива будет содержать размер файла. Для доступа к строке номер i,

    используйте функцию seek или seekg, чтобы найти смещение для lineIndex[i].

    Размер строки номер i равен lineIndex[i+1] - lineIndex[i+1].

    Как написать процедуру общего назначения для копирования между входным

    ивыходным файловым потоком?

    Вам необходимо использовать потоковую функцию gcount() для получения

    ряда байт фактически читаемых в последнем неформатированном потоковом

    вводе. Вот функция copyStream:

    void copyStream(fstreamit fin, fstreamil fout,

    unsigned char* buffer, int buffSize)

    {

    int n;

    while (fin. read (buffer, buffaize))

    {

    n = fin.gcount();

    fout.write (buffer, n);

    }

    }

    Практикум

    Контрольные вопросы

    1. Верно или нет? Потоковые функции ввода/вывода read и write способны

    правильно считывать и записывать данные любого типа.

    2. Верно или нет? Потоковые функции ввода/вывода read и write способны

    правильно считывать и записывать данные любого типа, не имеющих указателей.

    3. Верно или нет? Функции seek и seekg расширяют файл, когда вы передаете

    индекс, который на один или более байт превышает текущий конец файла.

    4. Верно или нет? Аргументы функций seek и seekg не требуют проверки

    диапазона.

    Упражнение

    Создайте программу VSEARCH.CPP, модифицируя программу VIRTUAL.CPP.

    Класс VmArray в VSEARCH.CPP должен иметь функцию binSearch, которая

    проводит двоичный поиск в элементах сортированного массива. Добавьте цикл в

    конец функции main для поиска в массиве arr, используя неупорядоченные

    данные инициализирующего списка. (Элементы этого списка доступны при

    использовании данных-указателей.)

    Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11


    Приглашения

    09.12.2013 - 16.12.2013

    Международный конкурс хореографического искусства в рамках Международного фестиваля искусств «РОЖДЕСТВЕНСКАЯ АНДОРРА»

    09.12.2013 - 16.12.2013

    Международный конкурс хорового искусства в АНДОРРЕ «РОЖДЕСТВЕНСКАЯ АНДОРРА»




    Copyright © 2012 г.
    При использовании материалов - ссылка на сайт обязательна.