Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекція 9 (Файли).docx
Скачиваний:
29
Добавлен:
16.05.2015
Размер:
64.85 Кб
Скачать

Функція rewind ()

Функція rewind() встановлює покажчик поточної позиції у файлі на початок файлу, вказаного як аргумент цієї функції. Іншими словами, функція rewind() виконує "перемотування" (rewind) файлу. Ось її прототип:

void rewind (FILE * pf);

Щоб познайомитися з rewind(), змінимо програму з попереднього розділу таким чином, щоб вона відображала вміст файлу відразу після його створення. Щоб виконати відображення, програма після завершення введення "перемотує" файл, а потім за допомогою fback() читає його з самого початку. Зверніть увагу, що зараз файл необхідно відкрити в режимі читання/запису, використовуючи як аргумент, що задає режим, рядок "w+".

# include <stdio.h> # include <stdlib.h> # include <string.h> int main (void) {   char str [80];   FILE * fp;   if ((fp = fopen ("TEST", "w +"))== NULL) {     printf ("Помилка при відкритті файлу. \ n");     exit (1);   }   do {     printf ("Введіть рядок (порожню – для виходу): \ n");     gets (str);     strcat (str, "\ n"); / * введення роздільник рядків * /     fputs (str, fp);   } while (* str! = '\n');   / * Тепер виконується читання і відображення файлу * /   rewind (fp); / * встановити покажчик                   поточної позиції на початок файлу. * /   while (! feof (fp)) {     fgets (str, 79, fp);     printf (str);   }   return 0; }

Функція ferror ()

Функція ferror() визначає, чи відбулася помилка під час виконання операції з файлом. Прототип цієї функції наступний:

int ferror (FILE * pf);

де pf – допустимий покажчик файла. Вона повертає значення true (істина), якщо під час останньої операції з файлом сталася помилка, в іншому ж випадку вона повертає false (неправда). Так як при будь-якої операції з файлом встановлюється свою умову помилки, то після кожної такої операції слід одразу викликати ferror(), а інакше дані про помилку можуть бути втрачені.

У наступній програмі показано застосування ferror(). Програма видаляє табуляції з файлу, замінюючи їх відповідною кількістю пробілів. Розмір табуляції визначається макросом TAB_SIZE. Зверніть увагу, що ferror() викликається після кожної операції з файлом. При запуску цієї програми вказуйте в командному рядку імена вхідного і вихідного файлів.

/ * Програма замінює в текстовому файлі символи  табуляції пробілами і відстежує помилки. * / # include <stdio.h> # include <stdlib.h> # define TAB_SIZE 8 # define IN 0 # define OUT 1 void err (int e); int main (int argc, char * argv []) { FILE * in, * out;   int tab, i;   char ch;   if (argc! = 3) {     printf ("Синтаксис: detab <вхідний_файл> <вихідний файл> \ n");     exit (1);   }   if ((in = fopen (argv [1], "rb "))== NULL) {     printf ("Не можна відкрити% s. \ n", argv [1]);     exit (1);   }   if ((out = fopen (argv [2], "wb "))== NULL) {     printf ("Не можна відкрити% s. \ n", argv [2]);     exit (1);   }   tab = 0;   do {     ch = getc (in);     if (ferror (in)) err (IN);     / * Якщо знайдена табуляція, виводиться  відповідне число пробілів * /     if (ch == '\ t') {       for (i = tab; i <8; i + +) {         putc ('', out);         if (ferror (out)) err (OUT);       }       tab = 0;     }     else {       putc (ch, out);       if (ferror (out)) err (OUT);       tab + +;       if (tab == TAB_SIZE) tab = 0;       if (ch == '\ n' | | ch == '\ r') tab = 0;     }   } While (! Feof (in));   fclose (in);   fclose (out);  return 0; } void err (int e) { if (e == IN) printf ("Помилка при вводі. \ n");   else printf ("Помилка при виведенні. \ n");   exit (1); }

Стирання файлів

Функція remove() стирає вказаний файл. Ось її прототип:

int remove (const char * ім'я_файлу);

У разі успішного виконання ця функція повертає нуль, а в іншому випадку – ненульове значення.

Наступна програма стирає файл, вказаний в командному рядку. Однак спочатку вона дає можливість передумати. Утиліта, подібна до цієї, може стати в нагоді комп'ютерним користувачам-новачкам.

int main (int argc, char * argv []) {   char str [80];   if (argc! = 2) {     printf ("Синтаксис: xerase <ім'я файлу> \ n");     exit (1);   }   printf ("Стерти% s? (Y / N):", argv [1]);   gets (str);   if (toupper (* str) == 'Y')     if (remove (argv [1])) {       printf ("Не можна стіреть файл. \ n");       exit (1);     }   return 0; }

Дозапис потоку

Для дозапису вмісту вивідного потоку в файл застосовується функція fflush (). Ось її прототип:

int fflush (FILE * pf);

Ця функція записує всі дані, що знаходяться в буфері в файл, який вказаний за допомогою PF. При виконанні функції fflush() з порожнім (null) покажчиком файлу pf буде виконана дозапис в усі файли, відкриті для виведення.

Функції fread () і fwrite ()

Для читання і запису даних, тип яких може займати більше 1 байта, у файловій системі мови С є дві функції: fread() і fwrite(). Ці функції дозволяють читати і записувати блоки даних будь-якого типу. Їх прототипи наступні:

size_t fread (void * буфер, size_t коліч_байт, size_t лічильник, FILE * pf); size_t fwrite (const void * буфер, size_t коліч_байт, size_t лічильник, FILE * pf);

Для fread() буфер – це покажчик на область пам'яті, в яку будуть прочитані дані з файлу. А для fwrite() буфер – це покажчик на дані, які будуть записані у файл. Значення лічильник визначає, скільки зчитується або записується елементів даних, причому довжина кожного елемента в байтах дорівнює коліч_байт. (Пригадайте, що тип size_t визначається як один з різновидів цілого типу без знака.) І, нарешті, pf – це покажчик файлу, тобто на вже відкритий потік.

Функція fread() повертає кількість прочитаних елементів. Якщо досягнуто кінець файлу або сталася помилка, то повертається значення може бути менше, ніж лічильник. А функція fwrite() повертає кількість записаних елементів. Якщо помилка не відбулася, то повертається результат буде дорівнює значенню лічильник.

Як тільки файл відкритий для роботи з двійковими даними, fread() і fwrite() відповідно можуть читати і записувати інформацію будь-якого типу. Наприклад, наступна програма записує в дисковий файл дані типів double, int і long, a потім читає ці дані з того ж файлу. Зверніть увагу, як у цій програмі при визначенні довжини кожного типу даних використовується функція sizeof().

int main (void) {   FILE * fp;   double d = 12.23;   int i = 101;   long l = 123023L;   if ((fp = fopen ("test", "wb +"))== NULL) {     printf ("Помилка при відкритті файлу. \ n");     exit (1);   }   fwrite (& d, sizeof (double), 1, fp);   fwrite (& i, sizeof (int), 1, fp);   fwrite (& l, sizeof (long), 1, fp);   rewind (fp);   fread (& d, sizeof (double), 1, fp);   fread (& i, sizeof (int), 1, fp);   fread (& l, sizeof (long), 1, fp);   printf ("% f% d% ld", d, i, l);   fclose (fp);   return 0; }

Як видно з цієї програми, як буфер можна використовувати (і часто саме так і роблять) просто пам'ять, в якій розміщена змінна. У цій простій програмі значення, які повертаються функціями fread() і fwrite(), ігноруються. Однак на практиці ці значення необхідно перевіряти, щоб виявити помилки.

Одним з найбільш корисних застосувань функцій fread() і fwrite() є читання і запис даних користувача типів, особливо структур. Наприклад, якщо визначена структура

struct struct_type {   float balance;   char name [80]; } Cust;

то наступний оператор записує вміст cust у файл, на який вказує fp:

fwrite (&cust, sizeof (struct struct_type), 1, fp);