При написанні програм часто необхідно прочитати вміст директорія для визначення того, які файли там зареєстровані. На жаль, директорій MS-DOS не може бути відкритий як звичайний регулярний файл для читання або запису. У цім зв’язку доводиться використовувати спеціальні функції Turbo С, прототипи яких наведені у файлі <dir.h>.
#include <dir.h>
int findfirst( const char *filename, struct ffblk *ffblk, inl attrib )
Викликає функцію MS-DOS АН=4Eh для одержання інформації про перший файл
(у тому числі і про директорію), ім’я якого відповідає файлу, заданому в рядку
filename, а атрибути - атрибутам, заданим параметром attrib. Аргумент filename
указує на ASCIIZ-рядок вигляду
[накопичувач] [маршрут] ім’я_файлу [.розширення]
Ім’я файлу і розширення можуть включати спеціальні символи-шаблони “?”
і “*”, що задають відповідно пошук збігу по одному будь-якому символу або групі
будь-яких символів. Значення attrib може бути утворено операцією порозрядного
АБО констант із Табл.
9. Якщо не заданий накопичувач або маршрут, MS-DOS приймає
поточний накопичувач і поточні директорії. Якщо збіг знайдений, функція
повертає 0 і заповнює структурну перемінну по шаблону ffblk, на якій указує
ffblk. При відсутності збігу або у випадку помилки повертається -1 і в зовнішню
змінну errno записується код помилки. Функція встановлює errno в значення
ENOENT, якщо запитаний файл не існує, або в значення ENMFILE, повідомляючи, що
більше задовольняючих критерію пошуку файлів немає. Шаблон структури ffblk
включає поля, що входять у керуючий блок MS-DOS ‑ блок керування файлом,
або FCB (File Control Block). Порядок розташування полів у ffblk Turbo С
відрізняється від структури FCB.
struct ffblk {
char ff_reserved[ 21 ]; /* зарезервовано для MS-DOS */;
char ff_attrib; /* атрибут з елементу директорія */
unsigned ff_ftime; /* поле часу з елементу директорія */
unsigned ff_fdate; /* поле дати з елементу директорія */
long ff_fsize; /* поле розміру файла з елементу директорія */
char ff_name[ 13 ]; /*ASCIIZ- рядок з ім’ям і розширенням
байлу
з
елементу директорія, включаючи символ “.”
який
розділяє імя та розширення файлу */
}
Після успішного виконання функції, поле ff_name містить ASCIIZ-рядок
імені і розширення файлу, розділені символом ‘.’, файлу, який задовольняє
заданим критеріям пошуку. Байт атрибута цього файлу копіюється в поле
ff_attrib. Поле ff_fsize містить розмір звичайного файлу. Для директорія і
мітки тому це поле дорівнює 0. Поля ff_ftime і ff_fdate повідомляють відповідно
час і дату останньої модифікації файлу. Структура полів відповідає розглянутій
в розділі 2.3.
#include <dir.h>
int findnext( struct ffblk *ffblk )
Продовжує пошук збігів, початий функцією findfirst. Якщо збіг
знайдений, функція повертає 0 і заповнює структурну змінну по шаблону ffblk, на
якій вказує ffblk. При відсутності збігів або у випадку помилки повертається -1
і в зовнішню змінну ernno записується код помилки, функція встановлює ernno у
значення ENOENT, якщо запитаний файл не існує, або в значення ENMFILE, повідомляючи,
що задовольняючому критерію пошуку файлів більше немає.
#include <dir.h>
void fnmerge( char *path, const char *drive, const char *dir,
const
char *name, const char *ext )
В області пам’яті, на якій указує path, будується ASCIIZ-рядок специфікації
файлу по наданих компонентах. Компоненти специфікації задаються покажчиками на
ASCIIZ-рядки:
drive
- накопичувач, наприклад “a:”;
dir - маршрут директорія;
name - ім’я файлу;
ext - розширення імені файлу.
#include
<dir.h>
inl fnsplit( const char *path, char *drive, char *dir,
char
*name, char *ext )
“Розбирає” специфікацію файлу, задану ASCIIZ-рядком, на який
посилається path. У результаті розбору породжуються ASCIIZ-рядки:
drive
- накопичувач, наприклад "а:";
dir - маршрут директорія;
name - ім’я файлу;
ext розширення імені файлу.
Функція повертає ціле число, утворене об’єднанням по АБО символічних
констант:
WILDCARDS |
-
специфікація містить символи шаблону “?” і “*”; |
EXTENSION |
-
специфікація містить розширення імені файлу; |
FILENAME |
-
специфікація містить ім’я файлу; |
DIRECTORY |
-
специфікація містить субдиректорій; |
DRIVE |
-
специфікація містить букву накопичувача. |
#include <dir. h>
char *searchpath( const char *file )
Виконує пошук файлу, ім’я якого задає file. Пошук файлу виконується
спочатку в поточну директорії, а потім у всіх директоріях, зазначених рядком
середовища PATH. У випадку успіху функція повертає покажчик на внутрішню
статичну область пам’яті, у якій записується повна специфікація файлу. У
протилежному випадку повертає NULL.
Наведемо приклад програми, що виводить на екран інформацію про всі директорії і файли, що відповідають заданому шаблону. Шаблон задається першим аргументом командного рядка при запуску програми у виді
[ накопичувач ] [ маршрут ] ім’я_файлу [ розширення ]
Ім’я_файлу і розширення можуть містити символи “*” і “?”.
/*L4_2.C*/
#include <stdio.h>
# include <string.h>
#include <ctype.h>
#include <dos.h>
# include <dir.h>
void print_element( struct ffblk* );
int main( int argc, char **argv ) {
int new_drive;
static struct ffblk my;
iff( argc<2) { /* Чи всі аргументи задані? */
printf( “\a%s\n”, “Використання
програми:L4_2 "\
“[накопичувач]:маршрут\[шаблон_выбору_файлів]” );
return(1);
}
/* Перевірка завдання накопичувача. */
if( strchr( argv[ 1 ], ( int )’:’ ) !=
NULL ) {
new_drive =
toupper((int)*argv[1])-’A’;
if( setdisk(0xf) < new_drive) {
printf( “\a%s\n”, “Задано
неіснуючий накопичувач”);
return(2);
}
}
printf(“Элементи, що задовольняють
шаблону пошуку %s\n\n",
argv[1]);
/* Перша спроба знайти збіг */
if( findfirst( argv[1], &my, 0xff
)== -1 ) {
printf( “\a%s\n”, “Немає таких
файлів або директорій” );
return(3);
} print_element( &my );
/* Цикл пошуку елементів, що
задовольняють шаблону */
while( findnext( &my ) == 0)
print_element( &my);
return(0);
}
/* Внутрішня функція круку елементу директорія. */
void print_element( struct ffblk *my ) {
printf(“%-12s%9lu байт”,
my->ff_name, my ->ff_fsize);
if( my->ff_attrib & FA_LABEL )
printf( “%s”, “Мітка тому” );
if( my->ff_attrib & FA_DIREC )
printf( “%s”, “Директорій” );
if( ту->ff_attrib & FA_ARCH )
printf( “%s”, “Архівний” );
if( my->ff_attrib & FA_RDONLY )
printf( “%s”, “Тільки що читається”
);
if( my->ff_attrib & FA_SYSTEM )
printf(“%s”, “Системний” );
if( my->ff_attrib & FA_HIDDEN)
printf( “%s”, “Що приховується”);
putchar( ‘\n’ );
}
Програма виконує дії, подібні команді dir COMMAND.COM, проте при цьому не виконується інтерпретація полів дати і часу елементу директорія. Відсутнє також опрацювання ключів /w, /p та ін.
![]() |
![]() |
![]() |