$ addaword
Введите слова для добавления в файл; для завершения введите символ # в начале строки, сумел многих удивить #
Содержимое файла:
Один
талантливый
программист
сумел
многих
удивить
Готово!
Как видите, fprintf() и fscanf() работают подобно функциям printf() и scanf(). В отличие от putc(), функции fprintf() и fscanf() принимают указатель на FILE в первом, а не последнем аргументе.
544 Глава 13
ФУНКЦИИ fgets() И fputs()
Вы уже сталкивались с fgets() в главе 11. Как и в отброшенной функции gets(), ее первым аргументом является адрес (типа char *), где должны сохраняться введенные данные. Второй аргумент — целое число, представляющее максимальный размер входной строки. Заключительный аргумент — это указатель файла, который идентифицирует файл, подлежащий чтению. Вызов функции выглядит следующим образом:
fgets(buf, STLEN, fp);
Здесь buf — это имя массива char, MAX — максимальный размер строки, a fp — указатель на FILE.
Как вы уже знаете, функция fgets() читает входные данные до появления первого символа новой строки — до тех пор, пока не будет прочитано количество символов, на единицу меньше верхнего предела, либо пока не будет обнаружен конец файла; затем fgets() добавляет завершающий нулевой символ, чтобы сформировать строку. Таким образом, верхний предел представляет максимальное количество символов плюс нулевой символ. Если fgets() удастся прочитать целую строку до достижения предельного числа символов, она поместит символ новой строки непосредственно перед нулевым символом, отметив конец строки. Функция fgets() возвращает значение NULL, когда сталкивается с EOF. Этим можно воспользоваться для проверки признака конца файла. В противном случае она возвращает переданный ей адрес.
Функция fputs() принимает два аргумента: адрес строки и указатель файла. Она записывает строку, находящуюся в указанной ячейке, в заданный файл. В отличие от puts(), функция fputs() при выводе не добавляет символ новой строки. Вызов fputs() выглядит следующим образом:
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, которое может
Читать дальше