МЕТОДИЧКА_С++_Ч2
.pdfПриклад 11.3. Складемо програму, по якій у файл запишеться послідовність цілих чисел, що вводяться з клавіатури, а потім ця послідовність буде прочитана і виведена на екран. Хай ознакою кінця введення буде число 9999.
//Запис і зчитування цілих чисел
#include <stdio.h> #include <conio.h> void main() { FILE *fp;
int x; clrscr ();
//відкриття потоку для запису if((fp=fopen("test.dat","w"))==NULL) {puts("Помилка відкриття файлу для запису!\n"); return;
}
puts("Введіть числа. Признак кінця - 9999"); scanf("%d",&x);
while(x!=9999) { putw(x,fp); scanf("%d",&x); }
fclose(fp);//закриття потоку в режимі запису //відкриття потоку для читання if((fp=fopen("test.dat","r"))==NULL) { puts("Помилка відкриття файлу для читання!\n"); return; }
while((x=getw(fp))!=EOF) printf("\n%d",x); fclose(fp);
getch();
}
Після завершення введення чисел у файл його необхідно закрити. При цьому
відбувається зкидання накопичених в буфері значень на диск. Тільки після цього
можна відкривати файл для читання. Покажчик встановлюється на початок потоку, і
подальше читання відбуватиметься від початку до кінця файлу.
Запис і читання блоків даних. Спеціальні функції обміну з файлами є тільки
для символьного і цілого типів даних. У загальному випадку використовуються
функції читання і запису блоків даних. З їх допомогою можна записувати у файл і
читати з файлу дійсні числа, масиви, рядки, структури. При цьому, як і для раніше
розглянутих функцій, зберігається форма внутрішнього представлення даних.
Функція запису блоку даних має прототип
int fread(void *buf,int bytes,int n, FILE *fptr);
Тут
51
buf — вказівник на адресу даних, які записуються в файл; bytes — довжина в байтах однієї одиниці запису (блоку даних); n — число блоків, які передаються у файл;
fptr — вказівник на потік.
Якщо запис виконався благополучно, то функція повертає число записаних блоків (значення n).
Функція читання блоку даних з файлу має прототип
int fwrite(void *buf, int bytes, int n, FILE *fptr);
По аналогії з попереднім описом легко зрозуміти сенс параметрів.
Приклад 11.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();
}
У цій програмі потік відкривається в режимі w+ (створення для запису з подальшим читанням). Тому закривати файл після запису не потрібно було. Новим елементом даної програми в порівнянні з попередніми є використання функції встановлення вказівника потоку в задану позицію. Її формат:
int fseek(вказівник_на_поток,зсув,початок_відліку) ;
52
Початок відліку задається одній з констант, визначених у файлі stdio.h:
SEEK_SET (має значення 0) — початок файлу;
SEEK_CUR (має значення 1) — поточна позиція;
SEEK_END (має значення 2) — кінець файлу.
Зсув визначає число байт, на яке треба змістити покажчик щодо заданого початку відліку. Зсув може бути як позитивним, так і негативним числом. Обидва параметри мають тип long.
Форматний обмін з файлами. За допомогою функції форматного виводу можна формувати на диску текстовий файл з результатами обчислень, які представлені в символьному вигляді. Надалі цей файл може бути проглянутий на екрані, роздрукований на принтері, відредагований за допомогою текстового редактора. Загальний вид функції форматного виведення:
int fprintf(вказівник_на_поток,форматний_рядок,рядок_змінних);
Що використалася нами раніше функція printf() для організації виводу на екран є приватним варіантом функції fprintf(). Функція printf() працює лише із стандартним потоком stdin, який завжди зв'язується системою з дисплеєм.
Не буде помилкою, якщо в програмі замість printf() написати
fprintf(stdin..).
Правила використання специфікаторів форматів при записі у файли на диску такі самі, як і при виводі на екран .
Введення формату з текстового файлу здійснюється за допомогою функції fscanf(), загальний формат якої виглядає таким чином:
int fscanf(вказівник_на_потік,форматний_рядок,
список_адрес_змінних);
Даною функцією зручно користуватися в тих випадках, коли початкові дані заздалегідь готуються в текстовому файлі.
У наступному прикладі числові дані з файлу test.dat, отриманого в результаті виконання попередньої програми, вводяться в числові масиви X і Y. Для контролю значення елементів масивів виводяться на екран. Заздалегідь за
53
допомогою текстового редактора у файлі test.dat віддаляються два перші рядки із заголовками. В результаті у файлі залишаться тільки числа.
Приклад 11.5.
//Введення чисел з файлу
#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();
}
Функції для роботи з файлами вказані в таблиці 11.1.
Таблиця 11.1 Функції введення/виведення для роботи з файлами в стилі С( <stdio.h>).
Ім'я функції |
Прототип і призначення |
clearerr |
void clearerr(FILE *f); |
|
Функція очищає прапори помилок для потоку f (прапори помилок не |
|
скидаються, поки не буде викликана одна з функцій clearerr, |
|
fseek, fsetpos або rewind). |
fclose |
int fclose(FILE *f); |
|
Функція закриває потік введення/виведення f. |
feof |
int feof(FILE *f); |
|
Функція повертає EOF або значення, відмінне від 0, якщо досягнутий |
|
кінець файлу, інакше повертає 0. |
ferror |
int ferror(FILE *f); |
|
Функція повертає ціле, таке, що означає код помилки; 0 — |
|
відсутність помилки. |
fflush |
int fflush(FILE *f); |
|
Функція очищає буфер виводу за допомогою негайної посилки даних |
|
для запису на фізичний пристрій. При успішному завершенні |
|
повертає значення 0, інакше повертається значення EOF. |
fgetc |
int fgetc(FILE *f); |
|
Функція повертає черговий символ у формі іnt з потоку f. Якщо |
|
символ не може бути прочитаний, то повертається значення EOF. |
54
Продовження таблиці 11.1
Ім'я функції Прототип і призначення
fgetpos |
int fgetpos(FILE *f, fpos_t *pos); |
|
Функція повертає поточну позицію у файлі, пов'язаному з потоком f, і |
|
копіює значення за адресою pos. Це значення пізніше може |
|
використовуватися функцією fsetpos. Повертаєме значення має тип |
|
fpos_t. |
fgets |
char *fgets(char *s, int n, FILE *f); |
|
Функція читає не більш n-1 байт з потоку f в рядок s, припиняючи |
|
читання при виявленні символу нового рядка або кінця файлу. |
|
Символ нового рядка при читанні не відкидається, а поміщається в |
|
кінець рядка. Прочитаний рядок доповнюється обмежувачем рядка |
|
('\0'). При виявленні помилки або кінця файлу повертається NULL, |
|
інакше — вказівник на рядок s. |
fgetwc |
wint_t fgetwc(FILE *f); |
|
Функція повертає черговий символ у формі wint_t з потоку f. Якщо |
|
символ не може бути прочитаний, то повертається значення WEOF. Є |
|
аналогом функції fgetc для багатобайтних символів. |
fgetws |
wchar_t *fgetws(wchar_t *s, int n, FILE *f); |
|
Функція читає не більш за n-1 символів з потоку f в рядок s, |
|
припиняючи читання при виявленні символу нового рядка або кінця |
|
файлу. Символ нового рядка при читанні не відкидається, а |
|
поміщається в кінець рядка. Прочитаний рядок доповнюється |
|
обмежувачем рядка ('\0'). При виявленні помилки або кінця файлу |
|
повертається NULL, інакше — покажчик на рядок s. Є аналогом |
|
функції fgets для багатобайтних символів. |
|
|
fopen |
FILE *fopen(const char *fname, const char *mode); |
|
Функція відкриває файл з ім'ям fname для роботи в режимі, вказаному |
|
рядком mode. При успішному відкритті повертається вказівник на |
|
потік (таким чином, отриманий потік зв'язується з файлом), інакше — |
|
NULL. |
fprintf |
int fprintf(FILE *f, const char *fmt, ...); |
|
Функція записує в потік f змінні, список яких позначений |
|
багатокрапкою (...), у форматі, вказаному рядком fmt. Повертає число |
|
записаних символів. |
fputc |
int fputc(int ch, FILE *f); |
|
Функція записує символ ch в потік f. При помилці повертає значення |
|
EOF, інакше — записаний символ. |
fputs |
int fputs(const char *s, FILE *f); |
|
Функція записує рядок символів s в потік f. Символ кінця рядка у |
|
файл не записується. При помилці повертає значення EOF, інакше — |
|
невід’ємне число. |
fputwc |
w_int fputwc(w_int ch, FILE *f); |
|
Функція записує символ ch в потік f. При помилці повертає значення |
|
WEOF, інакше — записаний символ. Є аналогом функції fputc для |
|
багатобайтних символів. |
55
Продовження таблиці 11.1
Ім'я функції Прототип і призначення
fputws |
int fputws(const wchar_t *s, FILE *f); |
|
Функція записує рядок символів s в потік f. Символ кінця рядка у |
|
файл не записується. При помилці повертає значення WEOF, інакше |
|
— невід’ємне число. Є аналогом функції fputs для багатобайтних |
|
символів. |
fread |
size_t fread(void *buffer, size_t size, size_t count, |
|
FILE *stream); |
|
Функція зчитує connt елементів size байтів в область, задану |
|
вказівником buffer, з потоку stream. Функція повертає кількість |
|
прочитаних елементів, яка може бути менше count, якщо при читанні |
|
відбулася помилка або зустрівся кінець файлу. |
freopen |
FILE *freopen(const char *fname, const char *mode, |
|
FILE *f); |
|
Функція працює аналогічно fopen, але заздалегідь закриває потік f, |
|
якщо той був раніше відкритий. |
|
|
fscanf |
int fscanf(FILE *f,const char *fmt[,par1, par2,...]); |
|
Функція вводить рядок параметрів par1, раr2 і т.д. у форматі, |
|
визначеному рядком fmt, з файлу f. Повертає число змінних, яким |
|
привласнено значення. |
ftell |
long int ftell(FILE *f); |
|
Функція повертає поточну позицію у файлі, пов'язаному з потоком f, |
|
як довге ціле. |
fwide |
int fwide(FILE *stream, int mode); |
|
Функція визначає залежно від mode вид потоку — байт-орієнтований |
|
(mode < 0) або потік з багатобайтних символів (mode > 0). Повертає |
|
поточний вид потоку. |
fwprintf |
int fwprintf(FILE *f, const wchar_t *fmt, ...); |
|
Введення з файлу форматованих данних |
fseek |
int fseek(FILE *f, long off, int org); |
|
Функція переміщує поточну позицію у файлі, пов'язаному з потоком |
|
f, на позицію off, відлічувану від значення org, яке повинне бути |
|
рівне одній з трьох констант, визначених в <stdiо. h>: |
|
SEEK_CUR — від поточної позиції вказівника; |
|
SEEK_END — від кінця файлу; |
|
SEEK_SET — від початку файлу. |
fsetpos |
int fsetpos(FILE *f, const fpos_t *pos); |
|
Функція переміщує поточну позицію у файлі, пов'язаному з потоком |
|
f, на позицію *pos, заздалегідь отриману за допомогою функції |
|
fgetpos. |
|
|
remove |
int remove(const char *filename); |
|
Функція видаляє існуючий файл. У разі успіху повертає нульове |
|
значення, інакше — ненульове. |
56
Продовження таблиці 11.1
Ім'я функції |
Прототип і призначення |
rename |
int rename(const char *oldname, const char |
|
*newname); |
|
Функція перейменовує існуючий файл або теку. У разі успіху |
|
повертає нульове значення, інакше — ненульове. |
rewind |
void rewind(FILE *f); |
|
Функція очищає прапори помилок в потоці f і встановлює поточну |
|
позицію на початок файлу. Зтирає файл |
Послідовність виконання роботи
1.Уважно ознайомтеся з теоретичним матеріалом щодо виконання практичної роботи.
2.Вивчити :
основну термінологію, зв’язану з файловими структурами даних: файл і його структура, фізичний і логічний запис, методи доступу, форматні і безформатні записи, запис кінця файлу для файлів з послідовним доступом;
можливості мови програмування по обробці файлу з послідовною організацією: запис даних в файл, читання з файлу, додавання записів в файл, корегування записів і т.д.
3.Розробити алгоритм рішення у відповідності з завданням.
4.Скласти програму рішення задачі.
5.Оформити звіт до практичної роботи. Звіт повинен містити: тему, мету,
постановку задачі, алгоритм програми, текст програми і результати роботи програми.
Завдання до практичної роботи
Написати програму обробки файлу в відповідності з варіантом
індивідуального завдання (Таблиця 11.2).
57
Таблиця 11.2. Варіанти індивідуальних завдань.
вар. |
|
Завдання |
|
|
|
|
№ |
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|||||
1 |
Написати програму, яка зчитує з текстового файлу три речення і виводить їх |
|||||
|
в зворотньому напрямку. |
|
|
|
|
|
2 |
Написати програму, яка зчитує текст з файлу і виводить на екран тільки |
|||||
|
речення, які містять введене з клавіатури слово. |
|
|
|||
3 |
Написати програму, яка зчитує текст з файлу і виводить на екран тільки |
|||||
|
рядки, які містять двозначні числа. |
|
|
|
|
|
4 |
Написати програму, яка зчитує англійський текст з файлу і виводить на |
|||||
|
екран слова, які починаються з голосних букв. |
|
|
|||
5 |
Написати програму, яка зчитує текст з файлу і виводить його на екран |
|||||
|
змінюючи місцями кожні два сусідніх слова. |
|
|
|||
6 |
Написати програму, яка зчитує текст з файлу і виводить на екран тільки |
|||||
|
речення, які не містять ком. |
|
|
|
|
|
7 |
Написати програму, яка зчитує текст з файлу і визначає скільки в ньому слів |
|||||
|
які складаються з не більше ніж чотирьох літер. |
|
|
|||
8 |
Написати програму, яка зчитує текст з файлу і виводить на екран тільки |
|||||
|
цитати, тобто речення в лапках. |
|
|
|
|
|
9 |
Написати програму, яка зчитує текст з файлу і виводить на екран тільки |
|||||
|
речення , які складаються з заданої кількості слів. |
|
|
|||
10 |
Написати програму, яка зчитує англійський текст з файлу і виводить на |
|||||
|
екран слова тексту, які починаються і закінчуються на голосні букви. |
|
||||
11 |
Написати програму, яка зчитує текст з файлу і виводить на екран тільки |
|||||
|
рядки, які не містять двузначні числа. |
|
|
|
|
|
12 |
Написати програму, яка зчитує текст з файлу і виводить на екран тільки |
|||||
|
речення, які починаються з тире, перед яким можуть знаходитися тільки |
|||||
|
«Space» символи. |
|
|
|
|
|
13 |
Написати програму, яка зчитує англійський текст з файлу і виводить його |
|||||
|
на екран, замінив кожну першу літеру слів, які починаються з голосної |
|||||
|
букви, на прописну. |
|
|
|
|
|
14 |
Написати програму, яка зчитує текст з файлу і виводе його на екран, |
|||||
|
замінивши цифри від 0 до 9 на слова «нуль», «один»… «дев’ять», |
|||||
|
починаючи кожне речення з нового рядка. |
|
|
|
||
15 |
Написати програму, яка зчитує текст з файлу, знаходить саме довге слово, і |
|||||
|
визначає скільки разів воно зустрілося в тексті. |
|
|
|||
16 |
Написати програму, яка зчитує текст з файлу і виводить на екран спочатку |
|||||
|
питальні |
(рос.вопросительные), |
а |
потім |
викликувальні |
(рос. |
|
восклицательные) речення. |
|
|
|
|
|
17 |
Написати програму, яка зчитує текст зфайлу і виводить на екран, після |
|||||
|
кожного речення додаючи, скільки разів зустрілося в ньому введене з |
|||||
|
клавіатури слово. |
|
|
|
|
|
|
|
|||||
18 |
Написати програму, яка зчитує текст з файлу і виводить на екран всі його |
|||||
|
речення в зворотньому порядку. |
|
|
|
|
58
Продовження таблиці 11.2.
.вар Завдання №
19Написати програму, яка зчитує текст з файлу і виводить на екран спочатку речення, які починаються з однолітерних слів, а потім всі останні.
20Написати програму, яка зчитує англійський текст з файлу і виводить на екран речення, що містять максимальну кількість знаків пунктуації.
Приклади виконання роботи:
Написати програму, яка визначає, чи зустрічається в заданому текстовому файлі задана послідовність символів. Довжина рядка тексту не перевищує 80 символів,
текст не містить перенесень слів, послідовність не містить пробільних символів.
#include <fstream.h> #include <string.h>
int main(){ const int len = 81; char word[len], line[len];
cout << "Введіть слово для пошуку: ";
сіn >> word;
ifstream fin("text.txt", ios::in | ios::nocreate); // 3
if (!fin) |
{ cout << "Помилка відкриття файлу." << endl; |
|
return 1; } |
|
//4 |
while (fin.getline(line, len)) { |
// 5 |
|
if (strstr(line, word)) { |
// 6 |
|
cout << "Присутнє!" << endl; return 0; } |
|
|
} |
|
|
cout << "Відсутнє!" << endl; |
|
|
return 0; |
//7 |
|
} |
|
|
Скласти програму, по якій буде розрахована і записана у файл таблиця квадратних корненів для цілих чисел від 1 до 10. Для контролю ця ж таблиця виводиться на екран.
//Таблиця квадратних корнів
#include <stdio.h> #include <iostream.h> #include <math.h> void main() {
FILE *fp;
59
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();
}
Якщо тепер за допомогою текстового редактора (наприклад, що входе в систему програмування) відкрити файл test.dat, то на екрані побачимо:
Таблиця квадратних корнів
х |
sqrt(x) |
1.000000 |
1.000000 |
2.000000 |
1.414214 |
3.000000 |
1.732051 |
4.000000 |
2.000000 |
5.000000 |
2.236068 |
6.000000 |
2.449490 |
7.000000 |
2.645751 |
8.000000 |
2.828427 |
9.000000 |
3.000000 |
10.000000 |
3.162278 |
Тепер ці результати можна роздрукувати, включити в текст звіту і т. п.
Написати програму, яка зчитує текст з файлу і виводить на екран тільки питальні речення з цього тексту.
#include <fstream.h> #include <stdio.h> int main(){
ifstream fin("text.txt", ios::in | ios::nocreate);
if (!fin) { cout << "Помилка відкриття файлу" << endl; return 1; }
fin.seekg(0, ios::end); |
// 1 |
|
|
long |
len = fin.tellg(); |
// 2 |
// 3 |
char |
*buf = new char [len |
+ 1]; |
|
fin.seekg(0, ios::beg); |
|
// 4 |
60