Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lektsii_OP / T14.doc
Скачиваний:
137
Добавлен:
17.03.2016
Размер:
405.5 Кб
Скачать

Int fclose(file *filename);

Вона повертає 0 при успішному закритті файла і EOF у противному випадку.

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

Так для перейменування файла служить функція rename(), яка має наступний прототип:

int rename(const char* old_name, const char* new_name );

Дана функція змінює ім'я файлу, зазначеного в old_name на нове ім'я, вказане в new_name. Наприклад,

char old_name[] = "Name_1.txt";  // старе ім'я файла

char new_name[] = "Name_2.txt"; // нове ім'я имя файла

if (rename(old_name, new_name) == 0) // перейменування файла

        cout << "File successfully renamed \n";

else

        cout << "Error renaming file \n";

Якщо файл успішно перейменований, повертається нульове значення; у разі помилки повертається ненульове значення і макрос ERRNO ініціалізується відповідним кодом помилки.

Для видалення файлу використовується функція remove():

int remove(const char* filename);

Функція remove() видаляє файл, ім'я якого зазначено в параметрі filename. Наприклад,

if( remove( "file.txt" ) != 0 )             // видалення файла file.txt

      cout << "Error to deleting file \n";

else

      cout << "File successfully removed \n";

Робота з текстовими файлами

Як відомо, текстові файли є сукупністю символьних рядків змінної довжини. Задання типу файла, як текстового, у С-програмах здійснюється додаванням суфікса t до значення режиму відкриття файлу (наприкінці чи перед знаком “+”). Наприклад, створення текстового файла в режимі читання/запису:

FILE *f = fopen("D:\file.txt", "w+t");

Під час відкриття файла в текстовому режимі виконуються перетворення деяких послідовностей символів. Наприклад, символи нового рядка перетворюються у послідовності символів "повернення каретки" / "переведення рядка".

У С-програмах для читання-запису текстових файлів використовують, в основному, рядкові та символьні засоби введення-виведення (містяться у бібліотеці stdio.h). Так, якщо потрібно зчитати рядок із текстового файла або записати рядок у текстовий файл, то можна скористатися функціями введення-виведення рядків fputs() і fgets():

char *fgets(char *р, int n, FILE *f );

-

читанняn символів із файла f, в рядок, на який вказує покажчик р (з додаванням ’\0’);

int fputs(const char *р, FILE *f);

-

записуфайлfрядка, на який вказує покажчик р

Функція fgets() сканує вхідний потік до тих пір, поки не зустріне символ переведення рядка "\n" або поки число введених символів стане рівним n-1. Якщо рядок не може бути прочитаний (записаний), то повертається макрос EOF3.

Наприклад, функція порядкового запису текстової інформації у файл

void write_file()

{ char s[40]”;

FILE *f = fopen(“file.txt”,”wt”);

do

{ cout<<"Input string:"; gets(s);

fputs(s, f);

cout<<"Continue?(Y/N)"; cin>>c;

}

while((c!='n')&&(c!='N'));

fclose(f);

}

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

void read_file()

{ char s[40]”;

FILE *f = fopen(“file.txt”,”rt”);

while(!feof(f))

{ fgets(s, sizeof(s), f);

printf("%s\n",s);

}

fclose(f);

}

Оскільки кожен байт у текстових файлах представляє символ, то такі файли можна обробляти і посимвольно. Для символьного введення-виведення використовуються функції fgetc() і fputc():

int fgetc(FILE *f);

-

читаннясимвола із файла f;

int fputc(int c, FILE *f);

-

запис символаc в файлf.

Якщо символ не може бути прочитаний (записаний), то повертається значення EOF.

Наприклад, функція посимвольного запису текстової інформації у файл

void write_file()

{ char s[]=”The string to file ”;

FILE *f = fopen(“file.txt”,”wt”);

for (int i=0; i <strlen(s); i++)

putc (s[i], f);

fclose(f);

}

та функція посимвольного зчитування текстової інформації із файлу

void read_file()

{ char s[100];

FILE *f = fopen(“file.txt”,”rt”);

int i=0;

char ch;

while ((ch = fgetc(f)) != EOF)

s[i++]=ch;

s[i] = ‘\0’;

printf("%s\n", s);

fclose(f);

}

Слід зауважити, що у файлах, відкритих для читання і запису, потік повинен бути обнулений (очищений) після запису, перш ніж виконувати операції читання. Це може бути зроблено шляхом виклику функції fflush(), яка примусово записує дані з буфера у файл незалежно від ступеня заповнення буфера.

Наприклад,

void find()

{ char buf[80];

FILE *f= fopen("file.txt", "rt+");

if (f== NULL) perror("Error opening file");

else

{ fputs("тест", f);

fflush(f);                    // очистка потоку

fgets(buf, 80, f);

puts(buf);

fclose (f);

}

Функція perror(), яка використовується у даному прикладі, дозволяє виводити додаткове повідомлення перед стандартним повідомленням про помилку. Наприклад,

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

Відповідні дії по читанню/запису нетекстової інформації можна виконати за допомогою функцій форматованого введення-виведення fscanf() і fprintf():

int fscanf(FILE *f, const char *format, adr_1, …, adr_n);

-

зчитування даних iз файла f по формату format за адресами adr_1, …, adr_n

int fprintf(FILE *f, const char *format, arg_1, ..., arg_n);

-

запис у файл f по формату format списку аргументів arg_1, …, arg_n

Як результат, повертається кількість зчитаних (записаних) елементів або 0.

Нехай є структура, що зберігає інформацію про книги (назва, автор, рік видання):

struct TBook

{ char name[100];

author[100];

int year;

} book;

Тоді функції збереження відповідної інформації в текстовий файл і її зчитування із текстового файлу можуть мати вигляд:

void creat_file()

{ FILE *f = fopen("file.txt","wt");

if ( f== NULL) printf(“Cannot open file \n”);

else

{ cout<<" Enter number of records:"; cin>>n;

for (int i=0; i<n; i++)

{ scanf("%s", book.name);

scanf("%s", book.author);

scanf("%d", &book.year);

fprintf(f,"%s %s %d \n", book.name, book.author, book.year);

}

fclose(f);

}

}

void print_file()

{ FILE *f = fopen("file.txt","rt");

if ( f== NULL) printf(“File not found \n”);

else

{ while (! feof(f))

{ fscanf(f,"%s %s %d \n", book.name, book.author, &book.year);

printf("%s %s %d\n", book.name, book.author, book.year);

}

fclose(f);

}

}

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

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

Записати числовий масив до текстового файлу можна і іншим способом: перетворити елементи масиву на С-рядки, які записати до файла за допомогою функції fputs(). Наприклад, записування до файла цілочисельного масиву з 10-ти елементів:

char s[80];

int a[10];

FILE *f = fopen("file.txt","wt");

for (int i=0; i<10; i++)

{ itoa(a[i], s, 10); // перетворення поточного елемента масива a на С-рядок

strcat(s, "\n"); // долучення до С-рядка символа переведення на новий рядок

fputs(s, f); // записування С-рядка до файлу

}

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

for (int i=0; i<10; i++)

{ itoa(a[i], s, 10); // перетворення поточного елемента масива на С-рядок

strcat(s, " "); // додавання пробілу після чергового числа

fputs(s, f); // записування С-рядка до файлу

}

fputs("\n", f); // записування до файлу символа переведення на новий рядок

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

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