Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lab11.doc
Скачиваний:
4
Добавлен:
21.09.2019
Размер:
171.01 Кб
Скачать

1. Потоки і потік введення - виведення

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

Потік є файлом або фізичним пристроєм (наприклад, принтером або монітором), яким можна управляти за допомогою вказівників на об'єкт FILE (визначений у stdio.h). Об'єкт FILE містить різноманітну інформацію про потік, включаючи поточну позицію потоку, вказівники на відповідні буфери й індикатори помилки або кінця файла.

Програма ніколи не може створювати і копіювати безпосередньо об'єкти FILE, проте, вона може використовувати вказівники на файли, повернуті з функцій типу fopen.

Потік потрібно відкрити перед тим, як здійснювати ввід із нього чи вивід у нього. Відкритий потік зв'язується з іменованим файлом операційної системи (наприклад, “z:\\test.dat”) або пристроєм (наприклад, принтером). Функції, що відкривають потоки, це fopen, fdopen і freopen. Коли програма відкриває потік, то їй необхідно вказати, чи ви хочете читати з потоку, чи записувати в потік, чи робити і те, й інше. Ви повинні також зазначити, чи будете ви обходитись з даними з потоку як із текстом, чи як із двійковими даними.

2. Текстові і двійкові потоки

Текстові потоки використовуються для звичайних текстових файлів DOS, таких як файл, створений редактором Borland C. Потік вводу-виводу С припускає, що текстовий файл розділений на рядки, відділені за допомогою одного символу нового рядка (LF), який є ASCII символ переведення рядка. Текстовий файл DOS, проте, записується на диск із двома символами між кожній рядком - ASCII символами повернення каретки (CR) і перевід рядка (LF). У текстовому режимі Borland C перетворить пару повернення каретки/переведення рядка (CR/LF) в один символ переведення рядка (LF) при вводі; переведення рядка (LF) перетвориться в пару CR/LF при виводі.

Двійковий потік значно простіший, ніж текстовий. Ніяких перетворень не проводиться. Будь-які символи читаються і записуються без змін. Файл сприймається як суцільна послідодовність байтів.

Файл може бути оголошений і в текстовому, і у двійковому режимі без будь-яких проблем, якщо ви поінформовані і розумієте перетворення, що відбуваються в текстовому потоці. Borland C не "запам'ятовує", як файл був створений або модифікований.

Якщо режим перетворення не вказується, коли потік відчиняється, те він відкривається за замовчуванням, обумовленим у глобальній змінній _fmode. За замовчуванням _fmode настроєна на текстовий режим.

3. Буферизація потоків

Потоки, зв'язані з файлами, звичайно буферизують. Це дозволяє дуже швидко вводити або виводити одиночні символи так, як це роблять getc і putc. Ви можете створити ваш власний буфер, змінити розмір використовуваного буфера, або змусити потік не використовувати буфер за допомогою виклику setvbuf або setbuf. Буфери потоків, що створюються користувачем, дуже корисні для перевірки вводу і виводу до того, як виникнуть певні системні помилки.

Буфер автоматично очищується при його заповненні, при створенні потоку і при нормальному завершенні програми. Ви можете використовувати fflush і flushall для очищення буфера.

При використанні функції setbuf() розмір буфера визначається системною константою BUFSIZ, що визначена в файлі stdio.h. Синтаксис функції виглядає наступним чином:

void setbuf( FILE *stream, char *buffer );

Розглянемо наступний приклад

#include<stdio.h>

char myBuf[50];

main(){

setbuf(stdout, myBuf); //спробуйте закоментувати

fputs("In stdout\n", stdout);

fputs("In stderr\n", stderr);

fputs("In stdout again\n", stdout);

fflush(stdout);

return(0);

}

В даному випадку програма зв’язує буфер myBuf з stdout, вивід в stdout відбувається тільки після виконання fflush(stdout). Якщо закоментувати оператор setbuf(), програма виводить повідомлення кожного оператора fputs() одразу після його виконання.

Використовуючи функцію setvbuf(), ми задаємо розмір буфера явно, а не за допомогою константи BUFSIZ. Синтаксис функції:

int setvbuf( FILE *stream, char *buffer, int mode, size_t size );

В даному випадку mode визначає режим буферизації, size - розмір буфера в байтах. У випадку успішного виконання функція повертає значення 0 і інше значення, якщо неправильно вказано тип або розмір буфера.

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

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

Якщо ви одночасно записуєте і зчитуєте дані з потоку, то ви не можете вільно змішувати оператори читання і запису. Ви повинні очистити буфер потоку між записом і читанням. Виклик fflush, flushall або fseek очищає буфер і дозволяє вам перемінити операції. Для максимальної переносимости ви повинні очищати буфер, навіть якщо він не використовується, тому що інші системи можуть мати додаткові обмеження на змішування операцій вводу-виводу навіть без буфера.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]