Выбрать главу

 fclose(fp);

 return 0;

}

Использовать функции fread() и fwrite() для считывания и записи блоков данных более эффективно, чем многократно вызывать функции fgetc() и fputc().

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

С-система ввода-вывода позволяет выполнять операции считывания и записи данных с произвольным доступом. Для этого служит функция fseek(), которая устанавливает нужным образом индикатор позиции файла. Ее прототип таков.

int fseek(FILE *fp, long numbytes, int origin);

Здесь параметр fp — файловый указатель, возвращаемый функцией fopen(), параметр numbytes — количество байтов относительно исходного положения, заданного параметром origin. Параметр origin может принимать одно из следующих макроимен (определенных в заголовке stdio.h).

Следовательно, чтобы переместить индикатор позиции в файле на numbytes байтов относительно его начала, в качестве параметра origin необходимо использовать значение SEEK_SET. Для перемещения относительно текущей позиции используйте значение SEEK_CUR, а для смещения с конца файла — значение SEEK_END.

Нулевое значение результата функции свидетельствует об успешном выполнении функции fseek(), а ненулевое— о возникновении сбоя. Как правило, функцию fseek() не рекомендуется использовать для файлов, открытых в текстовом режиме, поскольку преобразование символов может привести к ошибочным перемещениям индикатора позиции в файле. Поэтому лучше использовать эту функцию для файлов, открытых в двоичном режиме. Например, если вам нужно считать 234-й байт в файле test, выполните следующий код.

int func1()

{

 FILE *fp;

 if((fp=fopen("test", "rb")) == NULL) {

  printf("He удается открыть файл.\n");

  exit (1);

 }

 fseek(fp, 234L, SEEK_SET);

 return getc(fp); /* Считывание одного символа, расположенного на 234-й позиции. */

}

Функции fprintf() и fscanf()

Помимо рассмотренных выше основных функций ввода-вывода, С-система ввода-вывода включает функции fprintf() и fscanf(). Поведение этих функций аналогично поведению функций printf() и scanf(), за исключением того, что они работают с файлами. Именно поэтому эти функции обычно используются в С-программах. Прототипы функций fprintf() и fscanf() выглядят так.

int fprintf(FILE * fp, const char *fmt_string, ...);

int fscanf(FILE * fp, const char *fmt_string, ...);

Здесь параметр fp — файловый указатель, возвращаемый функцией fopen(). Функции fprintf() и fscanf() работают подобно функциям printf() и scanf() соответственно, за исключением того, что их действие направлено на файл, определенный параметром fp.

Удаление файлов

Функция remove() удаляет заданный файл. Ее прототип выглядит так.

int remove(const char *filename);

Она возвращает нуль при успешном удалении файла и ненулевое значение в противном случае.

Приложение Б: Использование устаревшего С++-компилятора

Программы, приведенные в этой книге, полностью соответствуют стандарту ANSI/ISO для C++ и могут быть скомпилированы практически любым современным С++-компилятором, включая Visual C++ (Microsoft) и C++ Builder (Borland). Следовательно, при использовании современного компилятора у вас не должно быть проблем с компиляцией программ из этой книги. (В этом случае вам вообще не понадобится информация, представленная в этом приложении.)

Но если вы используете компилятор, созданный несколько лет назад, то при попытке скомпилировать наши примеры он может выдать целый список ошибок, не распознав ряд новых С++-средств. И в этом случае не стоит волноваться. Для того чтобы эти программы заработали со старыми компиляторами, нужно внести в них небольшие изменения. Чаще всего старые и новые С++-программы отличаются использованием двух средств: заголовков и пространств имен. Вот об этом и пойдет речь в этом приложении.

Как упоминалось в главе 2, инструкция #include включает в программу заданный заголовок. Для более ранних версий C++ под заголовками понимались файлы с расширением .h. Например, в старой С++-программе для включения заголовка iostream была бы использована следующая инструкция.