Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lexzii_08 / lexs_9_fajly.doc
Скачиваний:
17
Добавлен:
17.05.2015
Размер:
75.78 Кб
Скачать

Введення і виведення даних з файла.

В залежності від завдання яке вирішує ваша програма ви або читаєте дані з файла або записуєте їх. Існує три засоби зробити це в залежності від характеру даних у файлі. Ці засоби допускають виконання трьох можливих варіантів введення-виведення:

- прямий;

- символьний;

- форматний, що аналогічно функціям форматного, рядкового і символьного введення-виведення.

Пряме введення-виведення.

При використанні цього засобу читання або запис в файл відбувається байтовими блоками визначеного розміру. Згаданий блок повинен десь знаходитись в пам’яті; для визначення його положення використовується покажчик типу void.

Зверніть увагу на використання операції sizeof; це кращий засіб гарантувати, що прочитаєте необхідну кількість байтів. Якщо згадати, що ім’я масиву або структури є константним покажчиком; таким чином, використовувати ім’я структури в якості покажчика місця, куди повинна бути записана структура.

Приведемо приклад функції, яка зчитує дані з відкритого файлу в масив структур. Функція використовує деякі ще не розглядані оператори; найбільш важливим з яких є виклик функції fread() і супровідні йому операції. Звернемо увагу, що ця функція звертається до функції FileExists() для перевірки існування файлу; при відсутності файлу виводиться повідомлення про помилку і відбувається вихід із функції без читання даних:

int FileLoad(char *FileName,

struct NameRecord *pNames)

{

FILE *pDickFile;

Int counter = 1;

If((pDiskFile = FileExists(FileName) == NULL))

{

puts(“File Does Not Exist”);

return 0;

}

else

{

pDiskFile = fopen(FileName,”r”);

while(!feof(pDiskName))

{

fread(&pNames[counter++],

sizeof(struct NameRecord),

1, pDiskFile);

}

fclose(pDiskFile);

}

return counter – 1;

}

Символьне введення-виведення.

Більш рідко використовують функції введення-виведення файлових потоків, які працюють з рядком або з одним символом. Нижче приведені прототипи цих функцій:

int fgetc(FILE *file_pointer);

int fputc(FILE *file_pointer);

char *fgets(char *buffer, int numch, FILE *fpointer);

char *fputs(const char *str, FILE file_pointer);

Функція fgetc() повертає значення одного символу з файла, на який поставлений покажчик; putc() записує в файл один символ. Функції fgets() i fputs() використовуються для роботи з цілими рядками.

Форматне введення-виведення.

Також існують функції введення-виведення файлового потоку, які є аналогами функцій scanf() i printf(). Це функції fscanf() i fprintf(). Їх прототипи:

int fprintf(FILE *file_pointer,

const char *format…);

int fscanf(FILE *file_pointer, const char *format…);

Для роботи з файлами використовуються такі функції:

  • fread() – призначена для прямого читання даних з відкритого файла; її прототип:

int fread(void *buffer, int blocksize, int blocks, FILE *fptr);

Передача функції покажчика (buffer) використовується для визначення в пам’яті місця зберігання даних; це може бути покажчик на змінну типу структура або на рядок. Крім того, функції треба передати розмір в байтах (blocksize) считуемого блока даних і кількість блоків (bloks), яке вона повинна повернути. Функції також потрібен покажчик на відкритий файл (fprt); це значення покажчика повертається функцією fopen(). Сама функція fread() повертає кількість прочитаних блоків.

Приклад для читання одного блоку даних із файла в структуру з іменем Name; ім’я структури – Namedef:

fread(&Name, sizeof(struct Namedef), 1, pFilePointer);

  • функція fwrite()

призначена для запису даних в відкритий файл.

Її прототип зберігається в файлі stdio.h, має вигляд:

int fwrite(void *buffer, int blocksize,

int blocks, FILE *fprt);

Ця функція виконує записування даних із області пам’яті, визначеної покажчиком buffer. Вона записує необхідну кількість (blocks) блоків заданого розміру (blocksize) в байтах в відкритий файл, який визначає покажчик fprt. Функція повертає кількість записаних блоків. Оператор для запису даних із структури з іменем Name в файл, визначений покажчиком pFilePointer буде мати такий вигляд:

fwrite(&Name, sizeof(sttruct NameDef), 1,

pFilePointer);

  • функція fclose()

закриває файл і зв’язаний з ним потік даних.

Її прототип:

int fclose(FILE *file_pointer);

При успішному закриттю потоку, функція повертає нуль, в випадку помилки повертає -1. file_pointer є значення, повертаєме при першому виклику функції fopen() для підготовки файла до роботи. Таким чином оператор закриття файлу має вигляд:

fclose(pFilePointer);

Якщо ви бажаєте повернути індикатор позиції в початкове положення скористайтесь функцією rewind(). Вона викликається таким чином:

  • Якщо ви бажаєте повернути індикатор позиції в початкове положення скористайтесь функцією rewind(). Вона викликається таким чином:

rewind(pFilePointer);

і дозволяє встановити індикатор позиції на початок файлу.

  • І остання функція в цьому розділі це функція fseek().

Її прототип:

int fseek(FILE *file_pointer, long offset,

int origin);

Ця функція виконує зміну на величину offset значення індикатора позиції файла, на який вказує file_pointer. Значення origin визначає початкове положення, відносно якого буде проводитись зміщення. Нульове значення цієї величини відповідає початку файла; при значені рівному 1, відлік буде вестись від поточної позиції в файлі; при значенні, рівному 2, відлік буде вестись від кінця файлу. Зміщення позиції буде виконано на кількість байтів, визначаємих значенням offset. Таким чином, щоб встановити позицію, що відстоїть на два записи від кінця файлу, потрібно викликати функцію з такими параметрами:

fseek(pFilePointer, 2*(sizeof(struct Record),2));

Існує ще декілька операцій з файлами про які ви повинні мати уявлення. Кожна з цих операцій – переіменування і вилучення файлів – має еквівалент серед команд операційної системи. Часто буває доречно перекласти таку роботу на саму операційну систему, щоб не завдавати собі зайвий клопіт, якщо помилково будуть вилучені потрібні файли.

Але існує така задача, як відкриття і робота з тимчасовими файлами. В процесі роботи може знадобитися тимчасове видалення даних з ОП і зберігання їх на диску. В цьому випадку після завершення роботи програми необхідно вилучити створені тимчасові файли, щоб не забруднювати диск.

Функція С rename() змінює ім’я існуючого файла даних.

Її прототип:

int rename(const char *old_name,

const char *new_name);

Якщо старе ім’я Old_Name, а нове New_Name, то переіменування виконано успішно, і -1 в іншому випадку. Збій при виконанні функції може бути зв’язаний з тим, що в дійсності старого імені не існує. Те ж саме відбудеться, якщо файл з новим іменем уже існує або ви спробуєте вийти за межі диску (Приклад, спробуйте перейменувати файл на диску С в файл на диску А, оскільки така операція уже буде не переіменуванням, а переміщенням файла).

Іноді файл потрібно вилучити.

Функція С remove() призначена для вилучення файла. Це найнебезпечніша із всіх функцій. Її прототип має вигляд:

remove(Filename);

Функція повертає нуль в випадку успіху і -1 в іншому випадку. Причина помилки може бути відсутність файла з вказаним ім’ям, існування у файла ознаки тільки для читання (в нього не можна записувати) або те, що він відкритий і знаходиться в роботі.

Найди помилку.

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

void DeleteFile(char *FileName)

{

char choise;

puts(“Дійсно ви хочете вилучити файл?”);

choise = getch();

remove(FileName);

if(choise == ‘y’)

puts(“Файл вилучено”);

return;

}

Відповідь: Виклик функції remove() відбувається до перевірки відповіді, отриманої від користувача; в такій ситуації функція завжди буде вилучати файл незалежно від відповіді користувача. Вірною буде така програма:

void DeleteFile(char *FileName)

{

char choise;

puts(“Дійсно ви хочете вилучити файл?”);

choise = getch();

if(choise == ‘y’)

{

remove(FileName);

puts(“Файл вилучено”);

return;

}

else

{

puts(“Файл не вилучено”);

return;

};

Соседние файлы в папке lexzii_08