Видалення файлів виконують функції remove() та unlink(). Фактично remove() являє собою макро, описане в заголовному файлі <stdio.h> так:
#define remove( path ) unlink( path )
Наведемо опис функції unlink.
#include <stdio.h>
int unlink( const char *filename )
Видаляє файл, на ASCIIZ-рядок специфікації якого вказує filename. У
випадку успіху функція повертає 0. У протилежному випадку повертається -1 і код
помилки записується в зовнішню змінну errno. Якщо функція не може відшукати
файл, заданий параметром filename, errno встановлюється в значення ENOENT. Якщо
файл, що видаляється має атрибут “тільки для читання”, errno встановлюється в
значення EACCES.
Перейменування файлу здійснює функція rename. Необхідність у цій операції часто виникає при виконанні “резервних” копій файлів що редагуються (наприклад, зберігання “старої” копії файлу з новим розширенням імені .ВАК). Загальновживаною є така практика. Існуюча (“стара”) копія файлу перейменовується у файл із розширенням імені .ВАК. Потім нова копія файлу записується на диск під своїм ім’ям.
#include <dir.h>
int rename( const char *oldname, const char *newname)
Змінює ім’я файлу або директорія з заданого рядком oldname на задане
рядком newname. У випадку успіху функція повертає 0. У противному випадку
повертається -1 і в зовнішню змінну errno записується код помилки. Якщо файл
або директорій, ім’я якого задає рядок oldname, існує, або файл з ім’ям newname
не може бути створений, або oldname директорій, a newname задає інший
директорій, зовнішня змінна errno буде дорівнювати EACCES. Якщо файл з ім’ям oldname не існує, зовнішня
змінна errno дорівнює ENOENT. Функція працює в межах тільки одного
накопичувача. Спроба задати різні букви накопичувача в oldname і newname
призводить до повернення помилки ENOTSAM. При перейменуванні файлів вони
попередньо закриваються. Тому щоб уникнути непорозумінь варто перейменовувати
попередньо закриті файли.
Наведемо приклад програми, що виконує переміщення файлів з одного директорія в інший, тобто подібній команді rename COMMAND.COM, але працюючої і для різних накопичувачів. “Переміщення” на різні накопичувачі пов’язано з виконанням фізичної копії файлу на новий диск і знищенням файлу-джерела. Для копіювання використовується виклик повторної копії COMMAND.COM. Імена файлів задаються в командному рядку при запуску програми.
/* L4_4.C */
#include <stdio.h>
#include <ermo.h>
#include <string.h>
#include <process.h>
#include <io.h>
#define BLANK “ ”
int main( int argc, char **argv) {
char string[81]=”copy “;
if( argc < 3 ) {
printf( “\а Використання програми
\п”\
“%s
<старе_ім’я> <новое_ім’я>
\п”, argv[0] );
return(1);
}
if( rename( argv[1], argv[2] ) ) {
if( errno == ENOTSAM ) { /* задані
різні накопичувачі */
/* Формування командного рядка
copy argv[1] argv[2]
і виконання її через оболонку
*/
strcat( string, argv[1] );
strcat( string, BLANK );
strcat( string, argv[2] );
if( system( string ) ) {
printf( “\а Помилка запуску
COMMAND.COM \n”);
return(2);
}
if( unlink( argv[1] ) ) {
printf( “\a Не можу видалити
%s\n”, argv[1] );
retiirn( 3 );
}
}
else {
printf( “\a Команда не виконана “
);
return( 4 );
}
}
return( 0 );
}
Наведемо приклад використання функції rename() при створенні резервних копій файлів. Програма приймає рядки з клавіатури і записує їх у файл на диску, зберігаючи попередній вміст. Ім’я файлу задається в командному рядку при запуску програми на виконання. Якщо файл не існує, він буде створений. Програма працює так. Спочатку в зарезервований масив - source зчитується весь файл. Потім на вільне місце, що залишилося, приймаються рядки з клавіатури. Їхній прийом завершується при введенні порожнього рядка. Після цього вихідний файл перейменовується у файл із розширенням імені .ВАК, а обновлений буфер записується у вихідний файл.
/*L4_5.C*/
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <dir.h>
#include <io.h>
#include <fcntl.h>
#include <stat.h>
#define BLANK “\n”
#define SIZE 1024
int main( int argc, char **argv ) {
char bak_name[128], drive[3], dir[64],
name[9], ext[5];
char source[SIZE], *src_ptr;
int fptr, ret;
if( argc < 2) { /* чи задані
параметри в командному рядку? */
printf( “\a Використання програми %s
<ім’я_файлe> \п”,
argv[0] );
return( 1 );
}
/* Запис у пам’ять усього вмісту файлу
argv[1] */
if( ( fptr=open(argv[1],
O_RDWR|O_APPEND|O_TEXT|O_CREAT,
S_IWRITE))==-1
) {
реrror( “\а Помилка відкриття
файлу”);
return( 2 );
}
if( ( ret=read( fptr, source,
SIZE))==-1) {
perror(“\a Помилка читання файлу”);
return(3);
}
close(fptr); /* перейменування потребує
закриття файлів */
src_ptr=source+ret; /* покажчик на
вільний байт */
if(ret==SIZE) { /* чи є ще місце у
буфері */
puts( “\a Не вистачає оперативної
пам’яті“ );
return( 4 );
}
puts("Вводьте рядки- Кінець вводу
- ENTER");
/* Нескінчений цикл прийому рядків з
клавіатури. */
while( strcmp( fgets( src_ptr, 128,
stdin), BLANK)) {
src_ptr += strlen( src_ptr );
if((src_ptr - source) > SIZE )
break;
}
/* Формування імені .ВАК - файлу. */
fnsplit(argv[1], drive, dir; name,
ext);
fnmerge(bak_name, drive, dir, name,
“.ВАК”);
/* Перейменування файлу argv[1] у файл
із розширенням .ВАК.
Попередньо знищується .ВАК-файл, якщо
він є. */
unlink( bak_name );
rename( argv[1], bak_name );
/* Створення нового файла з ім’ям
argv[1] */
if((fptr=open(argv[1],
O_WRONLY|O_TRUNC|O_TEXT|0_CREAT,
S_IWRITE )) ==
-1 ) {
printf(“\aПомилка відкриття файлу
%s”, argv[1]);
perror(“”);
return( 5 );
}
/* Запис у файл з ім’ям argv[1] */
if( write( fptr, source,
(unsigned)(src_ptr-source))==-1) {
perror( “\aПомилка запису у файл”);
return( 5 );
}
close( fptr );
return( 0 );
}
При виконанні перейменування іноді потрібно отримати унікальне ім’я файлу, що не співпадає з жодним з імен файлів у даному директорії. Виконати таку операцію допомагають функції бібліотеки Turbo С mktemp() або tmpnam().
#include <dir.h>
char *mktemp(char *template)
Використовуючи ASCIIZ-рядок шаблону, на початок якого вказує template,
утворює ім’я файлу, що не співпадає з жодним з імен у поточному директорії.
Сформоване ім’я записується в рядок template. Рядок template має вид
baseXXXXXX, де base - набір, що містить не більш шести будь-яких символів, які
обов’язково включаються в ім’я що генерується; символи “X” позначають позиції,
що будуть замінені символами унікального імені, причому третій із них - це
завжди символ “.”. Функція mktemp починає генерацію імен із комбінації АА.ААА,
Вона повертає покажчик на сформований рядок (тобто покажчик template). У
випадку помилки повертається NULL.
#include <dir.h>
char *tmpnam( char *sptr )
Генерує ім’я файлу, яке не співпадає з жодним з імен файлів у поточному
робочому директорії. Отримане ім’я записується в буфері на початок якого вказує
sptr. Розмір буферу повинний бути 13 байт, тому що там поміщається і
символ “.”, що відокремлює ім’я файлу від розширення імені. Якщо sptr дорівнює
NULL, отримане ім’я зберігається в динамічно розподіленій області пам’яті і
перевизначається кожним таким викликом до tmpnam(). Функція повертає покажчик
на початок отриманого рядка імені файлу; у випадку помилки повертається NULL.
![]() |
![]() |
![]() |