Тема: Файлові структури даних в мові С++.
План.
Потокове введення – виведення в стандарті С.
Робота з файлами на диску (відкриття та закриття
файлів).
Запис та зчитування символів, цифр, блоків даних.
Потокове введення-виведення в стандарті С
Під введенням-виведенням в програмуванні
розуміється процес обміну інформацією між
оперативною пам'яттю і зовнішніми пристроями:
клавіатурою, дисплеєм, магнітними накопичувачами і
т. п.
Введення — це занесення інформації із зовнішніх
пристроїв в оперативну пам'ять, а виведення —
винесення інформації з оперативної пам'яті на
зовнішні пристрої.
Основним поняттям, пов'язаним з інформацією на
зовнішніх пристроях ЕОМ, є поняття файлу. Всяка
операція введення-виведення трактується як
операція обміну з файлами: введення — це читання з
файлу в оперативну пам'ять; виведення — запис
інформації з оперативної пам'яті у файл.
Аналогом поняття внутрішнього файлу в мовах С/С++ є
поняття потоку.
Потік — це байтова послідовність, яка передається в
процесі введення-виведення.
Потік повинен бути пов'язаний з яким-небудь зовнішнім
пристроєм або файлом на диску.
Будь-який файл розглядається як байтова
послідовність:
Стандартні потоки призначаються і відкриваються
системою автоматично. З початком роботи будь-якої
програми відкриваються 5 стандартних потоків, з яких
основними є наступні:
• stdin — потік стандартного введення (зазвичай зв’
язаний з клавіатурою);
• stdout — потік стандартного виведення (зазвичай зв’
язаний з дисплеєм);
• stderr — виведення повідомлень про помилки (зв’
язаний з дисплеєм).
Окрім цього, відкривається потік для стандартного
друку і додатковий потік для послідовного порту.
Робота з файлами на диску (відкриття та закриття
файлів).
Робота з дисковим файлом починається з оголошення
вказівника на потік.
Формат такого оголошення:
FILE *ім’я_вказівника;
Наприклад:
FILE *fp;
Наступний крок — відкриття потоку, яке проводиться за
допомогою стандартної функції fopen(). Ця функція
повертає конкретне значення для покажчика на потік і
тому її значення привласнюється оголошеному раніше
покажчику.
Відповідний оператор має формат:
Ім’я_вказівника=fopen(ім’я_файлу,
режим_відкриття);
Наприклад:
fp=fopen("test.dat","r");
Існують наступні режими відкриття потоку і відповідні їм
параметри:
Потік може бути відкритий або для текстового,
або для двійкового (бінарного) режиму
обміну.
Текстовий файл - це послідовність символів,
яка ділиться на рядки спеціальними кодами,
— повернення каретки (код 13) і переведення
рядка (код 10).
Якщо потрібно вказати на двійковий файл, то до
параметра додається буква b. Наприклад: rb,
або wb, або r+b.
Якщо при відкритті потоку з якої-небудь причини
виникла помилка, то функція fopen() повертає
значення константи null.
Рекомендується наступний спосіб відкриття:
FILE *fp;
if(fp=fopen("test.dat","r")==NULL
{ puts("He можу відкрити файл\n");
return;
}
Закриття потоку (файлу) здійснює функція fclose(),
прототип якої має вигляд:
int fclose(FILE *fptr);
Тут fptr позначає формальне ім'я вказівника на потік, що
закривається. Функція повертає нуль, якщо операція
закриття пройшла успішно. Інша величина означає
помилку.
Запис та зчитування символів, цифр, блоків даних.
Запис символів в потік проводиться функцією putc() з
прототипом
int putc(int ch, FILE *fptr);
Якщо операція пройшла успішно, то повертається записаний
символ. У разі помилки повертається константа EOF.
Зчитування символу з потоку, відкритого для читання,
проводиться функцією gets() з прототипом
int gets(FILE *fptr);
Функція повертає значення зчитаного з файлу символу.
Якщо досягнутий кінець файлу, то повертається значення
EOF. Відмітимо, що це відбувається лише в результаті
читання коду EOF.
Приклад 14.1. Складемо програму запису у файл символьної
послідовності, що вводиться з клавіатури. Хай ознакою
завершення введення буде символ *.
//Запис символів в файл
#include <stdio.h>
void main() {
FILE *fp;
char c;
if((fp=fopen("test.dat","w"))==NULL)
{
puts("He могу открыть файл!\n");
return; }
puts("Вводите символы. Признак конца - *");
while((c=getchar())!='*')
putc(c,fp);
fclose(fp); }
Приклад 14.2. Файл, створений в результаті роботи попередньої
програми, потрібно послідовно прочитати і вміст вивести на
екран.
//Читання символів з файлу
#include <stdio.h>
#include <conio.h>
void main () {
FILE *fp;
char c;
clrscr () ;
if((fp=fopen("test.dat","r"))==NULL)
{puts("He вдалося відкрити файл!\n");
return;}
while((c=getc(fp)) !=EOF)
putchar(c) ;
getch();
fclose(fp); }
Запис і читання цілих чисел. Запис цілих чисел в
потік без перетворення їх в символьну форму
проводиться функцією putw() з прототипом
int putw(int,FILE *fptr);
Якщо операція пройшла успішно, то повертається
записане число. У разі помилки повертається
константа EOF.
Зчитування цілого числа з потоку, відкритого для
читання, проводиться функцією getw() з прототипом
int getw(FILE *fptr);
Функція повертає значення зчитаного з файлу числа.
Якщо прочитаний кінець файлу, то повертається
значення EOF.
Запис і читання блоків даних.
Спеціальні функції обміну з файлами є тільки для символьного і
цілого типів даних. У загальному випадку використовуються
функції читання і запису блоків даних. З їх допомогою можна
записувати у файл і читати з файлу дійсні числа, масиви, рядки,
структури.
Функція запису блоку даних має прототип
int fread(void *buf,int bytes,int n, FILE *fptr);
Тут
buf — вказівник на адресу даних, які записуються в файл;
bytes — довжина в байтах однієї одиниці запису (блоку даних);
n — число блоків, які передаються у файл;
fptr — вказівник на потік.
Якщо запис виконався благополучно, то функція повертає число
записаних блоків (значення n).
Функція читання блоку даних з файлу має прототип
int fwrite(void *buf, int bytes, int n, FILE *fptr);
Приклад 14.4. Наступна програма організовує запис блоком у файл рядка
(символьного масиву), а також читання і виведення на екран записаної
інформації.
#include <string.h>
#include <stdio.h>
#include <conio.h>
void main() {
FILE *stream;
char msg[]="this is a test";
char buf[20];
if ((stream=fopen("DUMMY.FIL", "w+"))==NULL)
{
puts("Помилка відкриття файлу.\n");
return;
}
//Запис рядка в файл
fwrite(msg, strlen(msg)+1, 1, stream);
//встановлення вказівника на початок файлу
fseek(stream, 0, SEEK_SET);
//читання рядка з файлу
fread(buf, strlen(msg)+1, 1, stream);
printf("%s\n", buf);
fclose(stream);
getch();
}
Новим елементом даної програми в порівнянні з
попередніми є використання функції встановлення
вказівника потоку в задану позицію. Її формат:
int fseek(вказівник_на_поток,зсув,
початок_відліку);
Початок відліку задається одній з констант, визначених
у файлі stdio.h:
SEEK_SET (має значення 0) — початок файлу;
SEEK_CUR (має значення 1) — поточна позиція;
SEEK_END (має значення 2) — кінець файлу.
Зсув визначає число байт, на яке треба змістити
покажчик щодо заданого початку відліку. Зсув може
бути як позитивним, так і негативним числом. Обидва
параметри мають тип long.
Форматний обмін з файлами. За допомогою функції
форматного виводу можна формувати на диску
текстовий файл з результатами обчислень, які
представлені в символьному вигляді.
int fprintf(вказівник_на_поток,
форматний_рядок,рядок_змінних) ;
Правила використання специфікаторів форматів при
записі у файли на диску такі самі, як і при виводі на
екран .
Приклад 14.5. Складемо програму, по якій буде розрахована і записана у файл
таблиця квадратних корнів для цілих чисел від 1 до 10. Для контролю ця ж
таблиця виводиться на екран.
//Таблиця квадратних корнів
#include <stdio.h>
#include <iostream.h>
#include <math.h>
void main() {
FILE *fp;
int x;
fp=fopen("test.dat","w") ;
//Виведення на екран і в файл шапки для таблиці
printf("\t Таблиця квадратних корнів\n");
fprintf(fp, "\t Таблиця квадратних корнів\n");
printf("\t x\t\tsqrt(x)\n");
fprintf(fp, "\t x\t\tsqrt(x)\n");
//Обчислення і виведення таблиці квадратного корня
//на екран і в файл
for(x=1; x<=10; x++)
{ printf("\t%f\t%f\n",float(x) , sqrt(float(x))) ;
fprintf(fp,"\t%f\t%f\n",float(x) , sqrt(float(x)));
}
fclose(fp);
cin.get();
}
Введення формату з текстового файлу здійснюється за допомогою функції
fscanf(), загальний формат якої виглядає таким чином:
int fscanf(вказівник_на_потік,форматний_рядок,
список_адрес_змінних);
Приклад 14.6.
//Введення чисел з файлу
#include <stdio.h>
#include <iostream.h>
#include <math.h>
void main() {
FILE *fp;
int i ;
float x[10], y[10];
fp=fopen ("test.dat", "r") ;
for(i=0; i<10; i++)
{ fscanf(fp, "%f%f",&x[i],&y[i]);
printf("%f %f\n",x[i],y[i]);
}
fclose(fp);
cin.get();
}
|