Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Название:Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:0101
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание
Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
fputs(buf, fp);
Здесь buf является адресом строки, a fp идентифицирует целевой файл.
Поскольку fgets() сохраняет символ новой строки, a fputs() не добавляет этот символ, они хорошо работают в тандеме. Как было показано в листинге 11.8, они успешно действуют вместе, даже когда STLEN меньше длины входной строки.
Произвольный доступ:
fseek() И ftell()
Функция fseek() позволяет трактовать файл подобно массиву и переходить непосредственно к любому байту в файле, открытом с помощью fopen(). Чтобы ознакомиться с работой fseek(), давайте напишем программу (листинг 13.4), которая отображает содержимое файла в обратном порядке. Обратите внимание, что fseek() принимает три аргумента и возвращает значение int. Функция ftell() возвращает текущую позицию в файле как значение long.
Листинг 13.4. Программа reverse.с
Файловый ввод-вывод 545
Вот вывод программы для одного из файлов:
Введите имя файла для обработки:
Cluv
.С екызя ан ьтавориммаргорп ястиварн енм огесв ешьлоБ
В этой программе применяется двоичный режим, поэтому она может иметь дело как с текстовыми файлами MS-DOS, так и с файлами Unix. Однако ее работа может оказаться некорректной в среде, в которой для текстовых файлов используется какой- то другой формат.
На заметку!
Если вы запускаете программу в среде командной строки, то программа ожидает, что файл с указанным именем находится в том же каталоге (или папке), что и сама исполняемая программа. Если программа запускается из IDE-среды, то каталог, в котором производится поиск файла, зависит от реализации. Например, по умолчанию Microsoft Visual Studio 2012 просматривает каталог, содержащий исходный код, a XCode 4.6 ищет файл в каталоге, где расположен исполняемый файл.
Теперь нам нужно обсудить три темы: как работают функции fseek() и ftell(), каким образом применяется двоичный поток данных и как делать программу переносимой.
Работа функций fseek() И ftell О
Первым из трех аргументов функции fseek() является указатель FILE на файл, в котором будет производиться поиск. Файл должен быть открыт с помощью fopen().
Второй аргумент fseek() называется смещением. Он показывает, насколько далеко необходимо переместиться от стартовой точки (ниже приведен список режимов стартовых точек). В этом аргументе должно передаваться значение long, которое может
546 глава 13 быть положительным (переместиться вперед), отрицательным (переместиться назад) или нулевым (остаться на месте).
Третий аргумент устанавливает режим, идентифицирующий стартовую точку. Начиная со стандарта ANSI, в заголовочном файле stdio.h указаны следующие именованные константы для режимов:
В более старых реализациях такие определения могут отсутствовать и вместо них для указания режимов используются числовые значения OL, 1L и 2L, соответственно. Вспомните, что суффикс L идентифицирует значения тип long. Или же в реализации могут быть предусмотрены константы, определенные в другом заголовочном файле. В случае сомнений обращайтесь к руководству пользователя или онлайновому справочнику.
Ниже приведены примеры вызова функции (fp — указатель файла):
fseek(fp, OL, SEEK_SET); // перейти в начало файла
fseeklfp, 10L, SEEK_SET); // перейти на 10 байтов от начала файла
fseeklfp, 2L, SEEK_CUR); // перейти вперед на 2 байта от текущей позиции
fseeklfp, OL, SEEK_END); // перейти в конец файла
fseeklfp, -10L, SEEK_END); // перейти назад на 10 байтов от конца файла
С такими вызовами связаны возможные ограничения, о которых речь пойдет позже в главе.
Значение, возвращаемое fseek(), равно 0, если все в порядке, и -1, если возникла ошибка вроде попытки выхода за границы файла.
Функция f tell() имеет тип long и возвращает текущую позицию в файле. В стандарте ANSI С она объявлена в stdio.h. Поскольку изначально функция f tell() была реализована в Unix, она указывает позицию в файле, возвращая количество байтов от начала файла, причем первый байт получает номер 0, второй — номер 1 и т.д. В ANSI С такое определение применяется к файлам, открытым в двоичном режиме, но не обязательно к файлам, открытым в текстовом режиме. Это одна из причин использования двоичного режима в листинге 13.5.
Теперь мы можем исследовать базовые элементы программы из листинга 13.5. Прежде всего, оператор
fseeklfp, OL, SEEK_END);
устанавливает позицию со смещением 0 байтов от конца файла. Это означает установку позиции в конец файла. Затем оператор
last = ftell(fp);
присваивает last количество байтов от начала до конца файла.
Далее следует цикл:
for (count = 1L; count <= last; count++)
{
fseeklfp, -count, SEEK_END); /* двигаться в обратном направлении */
ch = getc ( fp);
}
Файловый ввод-вывод 547
На первой итерации происходит позиционирование на первый символ перед концом файла (т.е. на финальный символ в файле). После этого данный символ выводится. На следующей итерации позиция устанавливается на предпоследний символ в файле, который затем выводится. Процесс продолжается до тех пор, пока не будет достигнут и выведен первый символ в файле.
Сравнение двоичного и текстового режимов
Программа в листинге 13.4 спроектирована так, чтобы работать в средах Unix и MS-DOS. В Unix имеется только один файловый формат, поэтому никакие специальные корректировки не нужны. Однако MS-DOS требует дополнительного внимания. Многие редакторы MS-DOS помечают конец текстового файла посредством символа . Когда такой файл открывается в текстовом режиме, в С этот символ распознается как признак конца файла. Тем не менее, когда тот же самый файл открывается в двоичном режиме, является обычным символом в файле, а действительный признак конца файла появляется позже. Он может находиться сразу после или же файл может быть дополнен нулевыми символами, чтобы сделать размер файла кратным, скажем, 256. Нулевые символы в среде MS-DOS не отображаются, поэтому мы предусмотрели код, предотвращающий вывод символа .
О другом отличии мы упоминали ранее: символ новой строки текстового файла в MS-DOS представлен с помощью комбинации \r\n. Программа на С, открывающая тот же самый файл в текстовом режиме, “видит” символы \r\n как просто \n, но в случае применения двоичного режима программа видит оба символа, т.е. \r и \n. По данной причине был включен код для подавления вывода \r. Поскольку текстовый файл в Unix обычно не содержит ни , ни \r, этот дополнительный код не затрагивает большинство текстовых файлов в Unix.
Функция ftell() может работать по-разному в текстовом и двоичном режимах. Форматы текстовых файлов многих систем заметно отличаются от модели Unix, в которых подсчет байтов от начала файла не дает осмысленной величины. В стандарте ANSI С утверждается, что для случая текстового режима ftell() возвращает значение, которое может быть использовано в качестве второго аргумента fseek(). Например, в MS-DOS функция ftell() может возвращать количество, при подсчете которого комбинация \r\n рассматривается как один байт.
Читать дальшеИнтервал:
Закладка: