|
|||||||||||||||||||||||||||||||||||||||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Позиционирование в потоке
Позиционирование в потоке. В начале главы были рассмотрены посимвольный, построчный и форматный обмены с файлами, организованными в виде потока байтов. Эти средства позволяли записать в файл данные и читать из него информацию только последовательно. Операция чтения (или записи) для потока всегда производится, начиная с текущей позиции в потоке. Начальная позиция чтения/записи в потоке устанавливается при открытии потока и может соответствовать начальному или конечному байту потока в зависимости от режима открытия потока. При открытии потока в режимах "r" и "w" указатель текущей позиции чтения/записи в потоке устанавливается на начальный байт потока, а при открытии в режиме "а" - в конец файла (за конечным байтом). При выполнении каждой операции ввода-вывода указатель текущей позиции в потоке перемещается на новую текущую позицию в соответствии с числом прочитанных (записанных) байтов. Рассмотрим средства позиционирования в потоке, позволяющие перемещать указатель (индикатор) текущей позиции в потоке на нужный байт. Эти средства дают возможность работать с файлом на диске, как с обычным массивом, осуществляя доступ к содержимому файла в произвольном порядке. В библиотеку языка Си включена функция fseek() для перемещения (установки) указателя текущей позиции в потоке на нужный байт потока (файла). Она имеет следующий прототип: int fseek (указатель_напоток, смещение, начало_отсчета); Смещение задается переменной или выражением типа long и может быть отрицательным, т.е. возможно перемещение по файлу в прямом и обратном направлениях. Начало отсчета задается одной из предопределенных констант, размещенных в заголовочном файле stdio.h: SEEK_SET (имеет значение 0) - начало файла; SEEK_CUR (имеет значение 1) -текущая позиция; SEEK_END (имеет значение 2) - конец файла.
Здесь следует напомнить некоторые особенности данных типа long. Этот тип определяется для целочисленных констант и переменных, которым в памяти должно быть выделено больше места, чем данным типа int. Обычно переменной типа long выделяется 4 байта, чем и определен диапазон ее значений. Описание данных типа long:
Константа типа long записывается в виде последовательности десятичных цифр, вслед за которыми добавляется разделитель L или 1. Примеры констант типа long:
331
В текстах программ лучше использовать L, чтобы не путать I с цифрой 1. Функция fseek () возвращает 0, если перемещение в потоке (файле) выполнено успешно, в противном случае возвращается ненулевое значение. Приведем примеры использования функции fseek(). Перемещение к началу потока (файла) из произвольной позиции:
Перемещение к концу потока (файла) из произвольной позиции:
В обоих примерах смещение задано явно в виде нулевой десятичной константы 0 L типа long. При использовании сложных типов данных (таких, как структура) можно перемещаться в потоке (файле) на то количество байтов, которое занимает этот тип данных. Пусть, например, определена структура:
Тогда при следующем обращении к функции fseek() указатель текущей позиции в потоке будет перемещен на одну структуру назад относительно текущей позиции:
Для иллюстрации работы с файлом в режиме произвольного доступа рассмотрим пример небольшого трехъязычного словаря, содержащего названия цифр от 1 до 9 на английском, немецком и французском языках. Для обслуживания словаря необходимы 2 программы: программа загрузки словаря в файл на диске и программа поиска слова в словаре (в ней используется функция fseek()). "База данных" словаря организована в файле vac.dat. Функция загрузки запрашивает названия для цифр от 1 до 9. Названия конкретной цифры (в предположении, что каждое название не превышает 9 букв) на всех трех языках записываются в одной строке через пробелы. Сформированная строка по нажатию клавиши <Enter> прочитывается в массив символов buf[ ]. Текст программы:
Введенные данные (представление цифры в формате целого числа и названия цифр на трех языках) побайтно выводятся в файл vac.dat, образуя в нем "записи", структура которых показана на рис. 7.2.
Рис. 7.2. Состав записи "Цифра"
Следующая программа перевода (trans) запрашивает сначала язык, на котором нужно выводить названия цифр, а затем в цикле запрашиваются цифры. Язык идентифицируется первой буквой своего русского наименования: 'а' или 'А' - для английского; 'н' или 'Н' - для немецкого; 'ф' или 'Ф' - для французского. Признаком завершения программы служит ввод цифры 0. Текст программы trans:
При вычислении позиции (pos) в файле, с которой начинается строка перевода, участвуют следующие составляющие: k-1 - выбирает подстроку (длиной 32 байта), в которой содержится перевод; 2 - учитывает длину поля цифры (2 байта); lang*10 - задает смещение до требуемого значения цифры в подстроке перевода.
На рис. 7.3 показаны составляющие смещения для искомого поля с переводом на немецкий язык.
Рис. 7.3. Составляющие смещения для записей в файле словаря
Предлагаем самостоятельно разработать функцию поиска в файле заданной подстроки и на ее основе написать программу перевода названий цифр с одного языка на другой. В табл. 7.3 приводятся названия цифр от 1 до 9 на трех языках.
Таблица 7.3
Трехъязычный словарь "Цифры
Кроме рассмотренной функции fseek(), в библиотеке функций языка Си находятся следующие функции для работы с указателями текущей позиции в потоке:
long ftelI( FILE *) - получить значение указателя текущей позиции в потоке;
void rewind (FILE *) - установить указатель текущей позиции в потоке на начало потока.
Необходимо иметь в виду, что недопустимо использовать функции работы с указателем текущей позиции в потоке для потока, связанного не с файлом, а с устройством. Поэтому применение описанных выше функций с любым из стандартных потоков приводит к неопределенным результатам. Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.006 сек.) |