МАРК РЕГНЕРУС ДОСЛІДЖЕННЯ: Наскільки відрізняються діти, які виросли в одностатевих союзах
РЕЗОЛЮЦІЯ: Громадського обговорення навчальної програми статевого виховання ЧОМУ ФОНД ОЛЕНИ ПІНЧУК І МОЗ УКРАЇНИ ПРОПАГУЮТЬ "СЕКСУАЛЬНІ УРОКИ" ЕКЗИСТЕНЦІЙНО-ПСИХОЛОГІЧНІ ОСНОВИ ПОРУШЕННЯ СТАТЕВОЇ ІДЕНТИЧНОСТІ ПІДЛІТКІВ Батьківський, громадянський рух в Україні закликає МОН зупинити тотальну сексуалізацію дітей і підлітків Відкрите звернення Міністру освіти й науки України - Гриневич Лілії Михайлівні Представництво українського жіноцтва в ООН: низький рівень культури спілкування в соціальних мережах Гендерна антидискримінаційна експертиза може зробити нас моральними рабами ЛІВИЙ МАРКСИЗМ У НОВИХ ПІДРУЧНИКАХ ДЛЯ ШКОЛЯРІВ ВІДКРИТА ЗАЯВА на підтримку позиції Ганни Турчинової та права кожної людини на свободу думки, світогляду та вираження поглядів
Контакти
Тлумачний словник Авто Автоматизація Архітектура Астрономія Аудит Біологія Будівництво Бухгалтерія Винахідництво Виробництво Військова справа Генетика Географія Геологія Господарство Держава Дім Екологія Економетрика Економіка Електроніка Журналістика та ЗМІ Зв'язок Іноземні мови Інформатика Історія Комп'ютери Креслення Кулінарія Культура Лексикологія Література Логіка Маркетинг Математика Машинобудування Медицина Менеджмент Метали і Зварювання Механіка Мистецтво Музика Населення Освіта Охорона безпеки життя Охорона Праці Педагогіка Політика Право Програмування Промисловість Психологія Радіо Регилия Соціологія Спорт Стандартизація Технології Торгівля Туризм Фізика Фізіологія Філософія Фінанси Хімія Юриспунденкция |
|
|||||||
Керування буферизацією даних
Нагадаємо, що високорівневий потокоорієнтований файловий обмін даними використовує проміжну буферизацію: дані з файлу заносяться спочатку у внутрішній буфер, а вже звідти зчитуються програмою (див. рис. 15.1). Якщо ж здійснюється запис у файл, то спочатку дані заносяться в буфер виведення, звідки переписуються у файл, коли буфер заповнено, або файл закривається. Проміжна буферизація може спричинити втрату даних у випадку некоректного завершення роботи програми: зациклення, збій у системі, відключення живлення тощо. Тому важливу інформацію доцільно відразу переписувати з буфера у файл, не чекаючи автоматичного скидання буфера.
Очищення/переписування внутрішнього буфера потоку fp виконує функція int fflush (FILE* fp);
Якщо потік fp відкрито для запису, то fflush () переносить у файл, пов'язаний з fp, увесь вміст відповідного буфера запису. Якщо ж fp є потоком введення, то fflush () очищає буфер цього потоку. В обох випадках потоки залишаються відкритими.
У разі успішного завершення функція fflush () повертає нуль, а в разі помилки - значення макроконстанти EOF.
Подамо приклад скидання даних у файл одразу після операції запису.
/* Перенесення у файл даних з буфера виведення */ FILE* fout; /* відкриття потоку fout для запису */ do { . . . . . /* формування даних виведення */ fwrite(&inform, sizeof(inform), 1, fout); /* запис у буфер */ fflush(fout); /* перенесення даних з буфера в файл */ } while (...); /* умова виконання циклу */
Для потоків введення, серед яких stdin, функцію fflush() застосовують, щоб звільнити буфер введення від зайвих даних чи символів. Таке очищення необхідне, зокрема, коли після введення даних функцією fscanf () чи scanf () наступною є операція читання символьного рядка за допомогою функцій fgets () або gets ().
Наведемо приклад очищення буфера у процесі введення даних з клавіатури.
/* Звільнення буфера введення від зайвих символів */ struct data { long index; char addr [120]; } inf; . . . /* початкова частина програми */ printf ("Індекс - "); scanf("%d", &inf.index); fflush(stdin); /* очищення буфера перед gets() * printf ("Адреса - "); gets(inf.addr);
Якби в наведеному програмному фрагменті оператора fflush(stdin); не було, то функція gets () зчитала би порожній рядок, оскільки після попереднього введення індексу за допомогою функції scanf () у вхідному буфері залишаються всі кінцеві нецифрові символи (щонайменше – “\n”).
Програміст може встановити власний буфер потоку або відмінити буферизацію, використовуючи функцію
void setbuf (FILE* fp, char* fbuf);
Якщо значенням параметра fbuf є NULL, то буферизація даних для вказаного потоку виконуватись не буде. Інакше fbuf повинен вказувати на ділянку пам'яті (або масив ) обсягом BUFSIZ. Макроконстанту BUFSIZ оголошено в <stdio.h>, значення у Borland C дорівнює 512.
Ширші можливості щодо керування буферизацією в процесах файлового обміну даними має функція
int setvbuf (FILE* fp, char* fbuf, int bmode, size_t bsize);
яка дає змогу не тільки встановити для потоку власний буфер, а й вказати його ємність і режим роботи. Параметр fbuf задає адресу ділянки оперативної пам'яті, що буде використовуватись як буфер потоку fp. Обсяг цієї ділянки повинен бути не меншим bsize. Якщо fbuf дорівнює NULL, то функція автоматично відкриває в динамічній пам'яті буфер заданої ємності.
Параметр bmode задає режим буферизації і може приймати одне з трьох значень:
· _IOFBF (у Borland C ця макроконстанта має значення 0) - буферизація виконується так само, як у стандартних режимах; · · _IOLBF (або 1) - у разі потоку виведення буфер скидається у файл кожен раз, коли в нього заноситься символ “\n” (рядкова буферизація); потоки введення буферизуються звичайним чином; · · _IONBF (або 2) - буферизація не виконується взагалі, значення fbuf та bsize ігноруються.
Останній параметр функції setvbuf () - bsize задає ємність створеного буфера і може приймати довільне цілочислове значення, що не перевищує 64 Кбайт. Розглянемо такі три приклади:
setvbuf(fp1, NULL, _IOFBF, 4096); setvbuf(fp2, mybuffer, _IOLBF, 128); setvbuf(fp3, nobuf, _IONBF, 0);
У першому прикладі для потоку fpl автоматично створюється буфер, ємність якого становить 4096 байтів, в усьому іншому процеси файлового обміну відбуватимуться звичайно. У другому прикладі для потоку fр2 буде використовуватись буфер mybuff ємністю 128 байтів, який попередньо має бути оголошений як масив або виділений у динамічній пам'яті. Обмін даними виконуватиметься через рядкову буферизацію. У третьому прикладі для потоку fp3 буферизацію відмінено.
У разі успішного виконання функція setvbuf () повертає нуль, а в разі невдачі - ненульове значення (код помилки). Обидві функції керування буферизацією setbuf () і setvbuf () повинні викликатись відразу після відкриття потоку.
У середовищі Borland C за замовчуванням встановлено, що стандартний потік виведення stdout не здійснює буферизації. Стандартні установки потоку в разі потреби можна змінити, наприклад, зробити виведення рядково буферизованим:
setvbuf(stdout, NULL, _IOLBF, 80);
Водночас, стандартний потік введення з клавіатури stdin є рядково буферизованим, ємність буфера становить 128 байтів. Змінити параметри буфера введення з клавіатури не можна, оскільки процес введення базується на внутрішній буферизації MS DOS. Тому найдовший рядок, який вводиться з клавіатури за одне звертання до gets () чи інших функцій потокоорієнтованого введення може містити тільки 127 символів.
Читання довших рядків треба організовувати програмнo, виконуючи послідовні звертання до функцій буферизованого введення або застосовуючи функції консольного введення з <conio.h>. Читайте також:
|
||||||||
|