Чтение онлайн

на главную - закладки

Жанры

Язык Си - руководство для начинающих

Д. МАРТИН

Шрифт:

Функция fseek позволяет нам обрабатывать файл подобно массиву и непосредственно достигать любого определенного байта в файле, открытом функцией fopen. Вот простой пример, показывающий, как она работает. Как и в наших предыдущих примерах, функция использует аргумент командной строки для получения имени файла, с которым она работает. Заметим, что fseek имеет три аргумента и возвращает значение типа int.

/*использование fscek

для печати содержимого файла */

#include <stdio.h&

main(number, names) /* не следует использовать argc и argv */

int number;

char *namеs[ ];

{

FILE *fp;

long offset = OL; /*обратите внимание, что это тип long */

if(number < 2)

puts("Мне нужно имя файла в качестве аргумента.");

else {

if((fp = fopen(names[1], "r")) == 0)

printf(" Я не могу открыть %s.\n", names[1]);

else {

while(fseek(fp, offset++, 0) == 0)

putchar(getc(fp));

fclose(fp); }

}

}

Первый из трех аргументов функции fseek является указателем типа FILE на файл, в котором ведется поиск. Файл следует открыть, используя функцию fopen.

Второй аргумент назван "offset" (вот почему мы выбрали данное имя для переменной). Этот аргумент сообщает, как далеко следует передвинуться от начальной точки (см. ниже); он должен иметь значение типа long, которое может быть положительным (движение вперед) или отрицательным (движение назад).

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

Код Положение в файле
0 начало файла
1 текущая позиция
2 конец файла

Функция fseek возвращает 0, если все хорошо, и – 1, если есть ошибка, например попытка перемещаться за границы файла. Теперь мы можем разъяснить наш маленький цикл:

while(fseek(fp, offset++, 0)==0)

putchar(getc(fp));

Поскольку переменная offset инициализирована нулем, при первом прохождении через цикл мы имеем выражение

fseek(fp, OL, 0)

означающее, что мы идем в файл, на который ссылается указатель fp, и находим байт, отстоящий на 0 байт от начала, т.е. первый байт. Затем функция putchar

печатает содержимое этого байта. При следующем прохождении через цикл переменная offset увеличивается до 1L, и печатается следующий байт. Посуществу, переменная offset действует подобно индексу для элементов файла. Процесс продолжается до тех пор, пока offset нe попытается попасть в fseek после конца файла. В этом случае fseek возвращает значение - 1 и цикл прекращается.

Этот последний пример чисто учебный. Нам нe нужно использовать fseek, потому что getc так или иначе проходит через файл байт за байтом; fseek приказала getc "посмотреть" туда, куда она сама уже собиралась посмотреть.

Вот пример (рис. 15.2), в котором выполняется что-то несколько более необычное (Мы благодарим Вильяма Шекспира за этот пример в пьесе "Двенадцатая ночь").

/* чередование печати в прямом и обратном направлениях */

#include <stdio.h>

main(number, names) /* вам не нужно применять argc и argv */

int number;

char *names[ ];

{

FILE *fp;

long offset = 0L;

if(number < 2)

puts(" Мне нужно имя файла в качестве аргумента.");

else {

if(fp = fopen(names[l], "r")) == 0)

printf(" Я не могу открыть %s.\n", names[l]);

else {

while(fseek(fp, offset++, 0) == 0)

{ putchar(getc(fp));

if(fseek(fp, -(offset + 3), 2) == 0)

putchar(getc(fp)); }

fclose(fp); }

} }

РИС. 15.2. Программа, чередующая печать в прямом и обратном направлениях.

Применение этой программы к файлу, содержащему имя "Мальволио", дает такой приятный результат:

МоаилльоввоьллиаоМ

Наша программа печатает первый символ файла, затем последний, затем второй, затем предшествующий последнему и т.д. Мы только добавили вот эти строки в последнюю программу:

if(fseek(fp, -(offset + 3), 2) == 0)

putchar(getc(fp));

Код 2 в операторе предполагает, что мы будем считать позиции от конца файла. Знак минус означает счет в обратном направлении. +3 стоит здесь потому, что мы начинаем с последнего регулярного символа файла и пропускаем несколько символов "новая строка" и EOF в самом конце файла. (Точное значение этой корректировки зависит от типа системы. Наши файлы имеют в конце по два символа новой строки, за которыми следуют два EOF, поэтому мы как раз их и обходим.)

Поделиться:
Популярные книги

Кодекс Крови. Книга IV

Борзых М.
4. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга IV

Девятый

Каменистый Артем
1. Девятый
Фантастика:
боевая фантастика
попаданцы
9.15
рейтинг книги
Девятый

Кодекс Охотника. Книга XII

Винокуров Юрий
12. Кодекс Охотника
Фантастика:
боевая фантастика
городское фэнтези
аниме
7.50
рейтинг книги
Кодекс Охотника. Книга XII

Его маленькая большая женщина

Резник Юлия
Любовные романы:
современные любовные романы
эро литература
8.78
рейтинг книги
Его маленькая большая женщина

Саженец

Ланцов Михаил Алексеевич
3. Хозяин дубравы
Фантастика:
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Саженец

Свет во мраке

Михайлов Дем Алексеевич
8. Изгой
Фантастика:
фэнтези
7.30
рейтинг книги
Свет во мраке

(Не)свободные, или Фиктивная жена драконьего военачальника

Найт Алекс
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
(Не)свободные, или Фиктивная жена драконьего военачальника

Вамп

Парсиев Дмитрий
3. История одного эволюционера
Фантастика:
рпг
городское фэнтези
постапокалипсис
5.00
рейтинг книги
Вамп

Инвестиго, из медика в маги 2

Рэд Илья
2. Инвестиго
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Инвестиго, из медика в маги 2

Последняя Арена 4

Греков Сергей
4. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 4

Хозяин Теней 2

Петров Максим Николаевич
2. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 2

Идеальный мир для Лекаря 8

Сапфир Олег
8. Лекарь
Фантастика:
юмористическое фэнтези
аниме
7.00
рейтинг книги
Идеальный мир для Лекаря 8

Неудержимый. Книга XI

Боярский Андрей
11. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XI

Двойник Короля 2

Скабер Артемий
2. Двойник Короля
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Двойник Короля 2