Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Обробка текстових файлів






Теоретичні основи

Зовнішнє ім’я файлу зазначається з урахуванням методики його по­дання для операційної системи. Воно може бути подане в повному вигляді (диск, шлях, ім’я: " C: \\Users\\a.txt") або в скороченому – з ураху­ванням принципів умовчання, що закладені в роботу операційної системи, а саме:

· якщо не зазначене ім’я диска, то розглядається активний диск;

· якщо не зазначений шлях до файлу, то розглядається поточна папка (поточний каталог);

· якщо шлях починається не із символу \, то відлік шляху почи­нається з поточної папки (слід пам’ятати про те, що в мові Сі символ \ є управляючим і в разі необхідності його подання він подвоюється: '\\').

Потокове введення/виведення

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

Потік – це файл разом із засобами буферизації. При роботі з потоком можна:

· відкривати і закривати потоки (зв’язувати покажчики на потоки з конкретними файлами);

· вводити і виводити символ, рядок, відформатовані дані, порцію даних довільної довжини;

· аналізувати помилки потокового введення/виведення і умову до­сягнення кінця потоку (файлу);

· керувати буферизацією;

· керувати покажчиком поточної позиції у потоці.

Якщо потік відкритий, то з ним зв’язується так званий покажчик (ін­дикатор) поточної позиції. Читання/записування даних здійснюється почи­наючи з того байту файлу, на який указує цей покажчик. При цьому покажчик поточної позиції автоматично «переміщається» по файлу на ту кількість байт, що відповідає зчитаному/записаному обсягу інформації. Результатом є те, що наступний сеанс читання/записування здійснюва­тиметься з орієнтацією на нове положення покажчика поточної позиції.

Обробка текстових файлів

Бібліотечні функції уведення/виведення підключаються через заго­ловний файл stdio.h, який, у свою чергу, автоматично підключається при підключенні файлу iostream.

Одним з видів файлів, якими може оперувати програма, написана мовою Сі, є текстові файли, що складаються з символьних рядків змінної довжини, завершуваних спеціальною комбінацією символів, називаною «кінцем рядка». Комбінація «кінець рядка» складається з двох символів – «повернення каретки» ('\xD', десятковий код 13) і «переведення рядка» ('\xA', десятковий код 10). Крім фізичного кінця файлу, як ознака кінця файлу в текстових файлах сприймається символ «кінець файлу» ('\x1A', десятковий код 26). Такий файл можна підготувати будь-яким текстовим редактором, у тому числі редактором, що вбудований в інтегроване сере­довище Visual Studio.

Для забезпечення доступу до файлового потоку використовується покажчик на тип FILE, що визначений у заголовному файлі stdio.h:

FILE *ім’я_покажчика;

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

FILE *fopen(char * ім’я_файлу, char *режим_відкриття);

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

Стандартними режимами відкриття для текстових файлів є:

· " w" – відкриття нового текстового файлу для записування;

· " r" – відкриття існуючого текстового файлу для читання;

· " a" – текстовий файл відкривається (або створюється, якщо він відсутній) для дозаписування в кінець;

· " w+" – новий текстовий файл відкривається для записування, читання і подальшого багаторазового виправлення з можливістю дозаписування в кінець файлу;

· " r+" – існуючий текстовий файл відкривається як для читання, так і записування;

· " a+" – текстовий файл відкривається або створюється (якщо він відсутній) як для читання, так і записування, причому записування здійснюється завжди в кінець файлу незалежно від положення покажчика поточної позиції.

Відкриття існуючого файлу в режимі " w" або " w+" забезпечує його повне відновлення.

Якщо потік відкритий у текстовому режимі, то прочитана з нього послідовність символів «повернення каретки» і «переведення рядка» пере­творюється на символ нового рядка '\n' (значення 10). При записуванні в потік здійснюється зворотне перетворення.

Текстовий режим можна явно позначити буквою t (наприклад, " r+t").

Приклади відкриття текстових файлів:

#include < iostream>
// Текст програми
FILE *f1, *f2, *f3;
// Текст програми
f1 = fopen(" a.txt", " rt");
char OutFileName[] = " C: \\USERS\\result.txt";
f2 = fopen(OutFileName, " w");
char *FileName = new char [256];
cout < < " \nInput the name of new file\n";
cin.getline(FileName, 256);
f3 = fopen (FileName, " w");

При помилках у відкритті потоку покажчик набуває значення NULL. Тому необхідно здійснювати перевірку значення покажчика, що можна зробити, наприклад, так:

FILE *f;
if ((f = fopen(" a.txt", " r")) == NULL)
{ // Дії при помилці
}

 

Закриття потоку здійснюється функцією

int fclose(FILE * покажчик_на_потік);

Повторне відкриття потоку потрібно передувати його закриттям.

При відкритті файлу в режимах " w", " w+", " r", " r+" покажчик поточної позиції установлюється на початок файлу, а при відкритті в ре­жимах " a" і " a+" – на його кінець.

Для читання (уведення) одного символу із файлу можна використо­вувати функцію

int fgetc(FILE * покажчик_на_потік);

або макрос

int getc(FILE * покажчик_на_потік),

а для записування (виведення) одного символу у файл – функцію

int fputc(int символ, FILE * покажчик_на_потік);

або макрос

int putc(int символ, FILE * покажчик_на_потік).

Як перший параметр функцій fgetc()і getc() може бути вико­ристаний будь-який вираз, результатом обчислення якого є деякий символ (у тому числі змінна або константа).

При помилках уведення/виведення, а також при виявленні ознаки кінця файлу перелічені вище функції повертають значення EOF.

Функція

char * fgets(char * рядок, int макс_кількість,
FILE * покажчик_на_потік);

здійснює читання (уведення) не більше (макс_кількість – 1) символів з файлу в рядок, що задається першим параметром (звичайний масив або покажчик на область пам’яті для зберігання символів). Якщо при цьому буде прочитаний символ нового рядка '\n', то він переноситься в сим­вольний масив, що адресується першим параметром) і читання припи­няється. За останніми занесеним у рядок символом записується ознака закінчення рядка (символ '\0'). При нормальному завершенні читання, функція повертає значення першого параметра (покажчик на перший еле­мент символьного масиву). У випадку помилки читання (у тому числі при досягненні кінця файлу, якщо жоден символ з файлу не прочитаний) функція повертає значення NULL, не змінюючи вміст масиву, що адре­сується першим параметром.

Для записування (виведення) у файл рядкових даних може бути ви­користана функція

 

int fputs(const char * рядок, FILE * покажчик_на_потік);

 

При виконанні цієї функції символ '\0' у файл не переноситься і не замінюється символом '\n'. У разі нормального завершення функція повертає останній виведений символ, а при помилці – значення EOF.

Крім того, використовуються такі функції форматного введення і ви­ведення відповідно:

 

int fscanf(FILE * покажчик_на_потік,
const char * форматний_рядок, список_покажчиків);

 

int fprintf(FILE * покажчик_на_потік,
const char * форматний_рядок, список_значень);

 

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

Другий параметр двох останніх функцій (форматний_рядок) може вміщувати як звичайні символи, так і специфікації перетворення при введенні та виведенні, що задаються деякими послідовностями символів, яким передує символ %.

Зокрема, слідом за символом % у форматному рядку функції fscanf() можуть йти такі символи (або послідовності символів), що визначають специфікації перетворення:

· d – уведення десяткового цілого (відповідний покажчик у списку_покажчиків повинен мати тип int *);

· i – уведення десяткового, вісімкового чи шістнадцяткового цілого (відповідний покажчик у списку_покажчиків повинен мати тип int *);

· f – уведення дійсного значення типу float (відповідний покаж­чик у списку_покажчиків повинен мати тип float *);

· lf – уведення дійсного значення типу double (відповідний по­кажчик у списку_покажчиків повинен мати тип double *);

· c – уведення одного символу (відповідний покажчик у списку_покажчиків повинен мати тип char *);

· s – уведення текстового рядка (відповідний покажчик у списку_покажчиків повинен мати тип char *).

У форматному рядку функції fprintf() слідом за символом % мо­жуть йти такі символи специфікації перетворення (перелік не повний):

· d або i – виведення десяткового цілого зі знаком;

· f – виведення дійсного значення (float або double) у вигляді числа з фіксованою точкою;

· e або E – виведення дійсного значення (float або double) у експонентній формі;

· c – виведення одного символу;

· s – виведення текстового рядка.

При нормальному завершенні функція fscanf() повертає кількість об’єктів, що отримали значення при введенні, а функція fprintf() – кількість виведених символів. У разі помилок уведення/виведення (у тому числі при виявленні ознаки кінця файлу під час уведення) обидві функції повертають значення EOF.

При введенні даних із файлу треба обов’язково перевіряти умову кінця файлу, оскільки читання ознаки кінця файлу призводить до помилки часу виконання. Для описаного вище потоку f1 це можна зробити, напри­клад, так:

int n;

while (fscanf(f1, " %d", & n)! = EOF)

{

// Дії

}

або

char s[300];

while (fgets(s, 300)! = NULL)

{

// Дії

}

 

чи

char c;

c = fgetc(f1);

while (! feof(f1)) // Див. нижче

{

// Дії

c = fgetc(f1);

}

 

Для позиціонування в потоці можна переміщати покажчик поточної позиції за допомогою наступної функції:

 

int fseek(FILE * покажчик_на_потік, long зміщення,
int початок_відліку);

 

При звертанні до цієї функції параметр зміщення задається змінною або виразом типу long і вказує, на скільки байт потрібно перемістити покажчик поточної позиції у прямому (> 0) або зворотному (< 0) напрям­ку. Початок_відліку вказує, по відношенню до якої позиції здійснюється зсув покажчика поточної позиції. Він задається однією з трьох констант:

 

SEEK_SET (== 0) – початок файлу;

SEEK_CUR (== 1) – поточна позиція;

SEEK_END (== 2) – кінець файлу.

 

Слід пам’ятати, що константа типу long записується у вигляді десяткового значення, слідом за яким додається суфікс L або l (напри­клад, 128L).

Функція fseek() повертає значення 0, якщо переміщення виконано успішно; інакше вона повертає нульове значення:

 

fseek(f, -1L, SEEK_CUR); – повернутися на 1 байт;

fseek(f, 0L, SEEK_END); – перейти на кінець потоку.

 

Деякі інші корисні функції:

long ftell(FILE * покажчик_на_потік); – повертає положення покажчика поточної позиції, що вимірюється в байтах від початку файлу, або значення (-1L) при помилці;

int fgetpos(FILE * покажчик_на_потік, fpos_t * позиція); – записує в область пам’яті, що адресується покажчиком позиція, положення покажчика поточної позиції файлу і повертає значення 0 при успішному виконанні або ненульове значення при помилці (тип fpos_t – це цілочисловий тип, що використовується для визначення положення покажчика поточної позиції файлу за допомогою функції fgetpos() або зміщення покажчика поточної позиції файлу функцією fsetpos(); див. нижче);

int fsetpos(FILE * покажчик_на_потік, fpos_t * позиція); – переводить покажчик поточної позиції файлу в позицію, яка зберігається в області пам’яті, що адресується покажчиком позиція, і повертає значен­ня 0 при успішному виконанні або ненульове значення при помилці;

void rewind(FILE * покажчик_на_потік); – переміщає покажчик поточної позиції на початок потоку;

int feof(FILE * покажчик_на_потік); – повертає ненульове зна­чення, якщо перед звертанням до цієї функції було прочитано ознаку кінця файлу, і 0, якщо спроби читання за кінцем файлу не було.

Якщо файл відкритий і для введення, і для виведення (режими " r+" і " a+"), то в разі потреби переходу від введення до виведення (або навпаки) необхідно обов’язково виконати примусове зміщення покажчика поточної позиції файлу (як варіант – на 0 байт відносно поточної позиції).

При роботі з файлами (будь-якими, а не тільки текстовими) корис­ними можуть бути такі дві функції, оголошені в заголовному файлі io.h:

int remove(const char *шлях); – знищення файлу, ім’я якого задане як параметр (файл повинен бути закритим);

int rename(const char *старе_ім’я, const char * нове_ім’я); – перейменування файлу або каталогу (файл повинен бути закритим). Якщо в новому імені файлу вказати інший шлях відносно ста­рого, файл буде перенесений. Каталог перенести неможливо.






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.