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); // записування до файлу символа переведення на новий рядок
Незважаючи на можливість збереження числових даних в текстових файлах, якщо треба компактно представляти такі дані у файлі, то числа слід все ж таки зберігати як числа, а не як рядки. При цьому доцільно використовувати бінарний режим доступу до файлу, оскільки буде гарантія, що будь-яке записане число не буде сприйматися як керуючий символ і буде коректно зчитане із файла.
