РОБОТА ІЗ БІНАРНИМИ ТА ТЕКСТОВИМИ ФАЙЛАМИ
НА МОВІ “CІ”
Мета практикуму – вивчення методів запису, зчитування та доповнення файлів на мові “СІ”.
1. ТЕОРЕТИЧНІ ВІДОМОСТІ
1.1. Для виконання операцій над файлами необхідно зв’язати фізичний файл, який знаходиться на диску, із файловою змінною – вказівником на об’єкт типу FILE. Вказівник на файл необхідно оголошувати, наприклад,
FILE *lst;
Тут FILE - ім’я типу, описане в заготовочному файлі stdio.h; lst – вказівник на файл;
Відкриття файла здійснюється за допомогою функції fopen, яка має наступний формат:
FILE *fopen (“фізичне ім’я файлу”, “режим”);
Функція fopen повертає вказівник на файл, або NULL, якщо під час відкриття файла виникла помилка. Фізичне ім’я файлу – це його повне ім’я, включаючи шлях до файлу.
Можливі режими:
“w”- текстовий файл відкривається для запису; якщо файл із вказаним іменем існує, то його вміст знищується;
“r”- текстовий файл відкривається для читання;
“a”- текстовий файл відкривається для доповнення, інформація додається в кінець файлу.
Режими відкривання файлу можуть бути доповнені специфікатором +,який означає режим виправлення – відкриття файлу одночасно і для запису, і для читання, наприклад:
FILE *lst;
lst=fopen(“D:\TC\file.txt”,”r+”);
Дані команди забезпечують відкриття вже існуючого текстового файлу D:\TC\file.txtяк для читання, так і для запису.
При переході від операцій запису до операцій читання необхідно застосовувати функцію fflush,яка забезпечує запис ще не збереженої інформації із буфера в файл. Вона має наступний формат:
int fflush (вказівник_на_файл);
Функція повертає EOF у разі помилки, та 0 в разі успішного виконання операції.
Після закінчення роботи з файлом його необхідно закрити командою fclose, яка має наступний формат:
int fclose(вказівник_на_файл);
Для видалення файла на диску слугує функція remove. Вона має наступний формат:
int remove(“ім’я_файлу”);
Для видалення файла на диску слугує функція remove, яка має наступний формат:
int rename(“старе_ім’я_файлу”, “нове_ім’я_файлу”);
У разі успішності виконання функцій remove, renameвони повертають 0, та ненульове значення у іншому випадку.
1.2. Форматоване виведення-введення даних у текстовий файл здійснюється за допомогою функцій fprint та fscanfвіповідно, які мають наступний формат:
int fprintf (вказівник_на_файл,рядок форматування, перелік змінних);
int fscanf (вказівник_на_файл,рядок форматування, перелік змінних);
Рядок форматування вміщує об’єкти трьох типів:
-звичайні символи, які виводяться на екран;
-специфікації перетворення, кожна з яких викликає виведення на екран значення чергового аргументу зі списку аргументів;
-керуючі символи (для початку з нового рядка, табуляції, звукового сигналу та ін.).
Специфікаціярозпочинається символом % і закінчується символом, який задає перетворення. Між цими знаками може стояти:
- знак мінус “-”, який вказує, що параметр при виведенні на екран повинен вирівнюватися по лівому краю. Інакше - по правому;
- рядок цифр, який задає розмір поля для виведення. Крапка, яка відділяє розмір поля від наступного рядку цифр, що визначає розмір поля для виведення розрядів після коми для типів float та double;
- символ довжини l, який вказує на тип long;
Далі вказується символ типу інформації виведення (перетворення):
d- десяткове число;
o- вісімкове число;
x- шістнадцяткове число;
c- символ (тип char);
s- рядок символів (string);
e- дійсне число в експоненціальній формі;
f- дійсне число (float);
g- використовується як e і f, але виключає виведення на екран незначущих нулів;
u- беззнаковий тип (unsigned);
p- вказівник (pointer).
Якщо після % записано не символ перетворення, то він виводиться на екран.
Керуючі символи:
\a- для короткочасної подачі звукового сигналу (alarm);
\b- для переведення курсору вліво на одну позицію (back);
\n- для переходу на новий рядок (new);
\r- для повернення каретки (курсор на початок поточного рядка) (return);
\t- для горизонтальної табуляції (tabulation);
\v- для вертикальної табуляції (vertical).
Приклад 1.Відкрити файл для запису. Записати у файл матрицю з 10 рядків і 10 стовпців.
#include <stdio.h>
main()
{int i,j;
FILE *lds;
lds=fopen("epa.txt","w");
/*Відкриття файлу на дискеті для запису. Якщо він не існує, то створюється автоматично*/
for(i=1;i<=10;i++)
for(j=1;j<=10;j++)
fprintf(lds,"%d%c",i+j-1,((j==10)?'\n':' '));
/*Запис даних до файлу*/
/*Перший аргумент – вказівник на файл, другий і третій такі ж як і для команди printf*/
fprintf(lds,"\n");
fclose(lds);
/*Закриття файлу*/
}
1.3. Для посимвольного введення та виведення даних у файл використовуються функції fgetc та fputc відповідно, які мають наступний формат:
int fgetc(вказівник_на_файл);
int fputc(вказівник_на_файл);
Функція fgetc повертає наступний символ із файла, на який вказує відповідний вказівник, або EOF в разі помилки. Функція fputs записує символ у файл, на який вказує відповідний вказівник, та повертає записаний символ, або EOF у випадку помилки.
Для введення-виведення рядків до файлу слугують функції fgets та fputs, які мають синтаксис, аналогічний fgetc, fputc.
1.4. Для введення-виведення даних до бінарних файлів застосовуються функції fwrite та fread відповідно. Вони мають наступний формат:
int fread (вказівник_на_масив, розмір_об’єкта, кількість_об’єктів , вказівник_на_файл); Функція забезпечує зчитування об’єктів у масив, на який вказує вказівник_на_масив, кількість об’єктів визначається як кількість_об’єктів, розміром розмір_об’єкта із файла, на який вказує вказівник_на_файл. Функція повертає кількість успішно записаних об’єктів.int fwrite(вказівник_на_масив, розмір_об’єкта, кількіст_об’єктів , вказівник_на_файл);Функція забезпечує запис об’єктів із масиву, на який вказує вказівник_на_масив, кількість об’єктів визначається як кількість_об’єктів, розміром розмір_об’єкта у файл, на який вказує вказівник_на_файл. Функція повертає кількість успішно записаних об’єктів. 1.5. Часто при роботі з файлами корисно використовувати по елементний доступ до файлу. Для цього застосовується функція fseek, що має формат: int fseek(вказівник_файла, зміщення, поч. значення);
Функція встановлює позицію із зміщенням відносно поч. значення у файлі, який визначається вказівником файла. Початкове значення може приймати наступні значення:
SEEK_SET – зміщення відносно початку файла;
SEEK_CUR – зміщення відносно поточного положення;
SEEK_END – зміщення відносно кінця файла;
Функція ftell повертає поточну позицію у файлі, та має наступний формат:
long ftell(вказівник_на_файл);
Приклад 2. Продемонструвати роботу із бінарними файлами.
#include <stdio.h>
#include <conio.h>
void main(void)
{
const n=10;
int a[10];
FILE *pfile;
int i,j,pos,start;
int *pstart;
pstart=&start;
/* вказівник вказує на змінну start */
clrscr();
printf("\nFilling vector with numbers...\n\n a=[ ");
for(i=0;i<10;i++)
{
a[i]=i+1;
printf("%d ",a[i]);
}
printf("]\n\nCreating binary file epa.dat for editing...");
pfile=fopen("epa.dat","w+b");
/*створення нового бінарного файлу для редагування */
j=fwrite(a,sizeof(int),n,pfile);
/* запис елементів вектора а у бінарний файл */
if(j<n) printf("\n\nAn error occured. Only %d of %d elements was written",j,n);
else printf("\n\nFile was filled with %d elements successfully",j);
fflush(pfile);
/* перед зчитуванням даних в режимі редагування обов’язково дописуємо вміст буфера у файл */
printf("\n\nEnter the number of element you want to read from bin file ");
scanf("%d",&j);
fseek(pfile,(j-1)*sizeof(int),SEEK_SET);
/*перехід до позиції необхідного елемента*/
pos=ftell(pfile);
/*Визначення позиції у файлі*/
fread(pstart,sizeof(int),1,pfile);
printf("\n\nSEEK_SET: %dth element position is %d, element is %d",j,pos,*pstart);
printf("\n\nPress any key to exit");
getch();
fclose(pfile); /* закриття файла */
}
2. ЗАВДАННЯ НА РОБОТУ
Розробити та запустити у роботу програму на мові програмування "СІ", яка вирішує задачу відповідно до заданого нижче варіанта.
2.1. Відкрити для редагування текстовий файл, ім'я якого задається з клавіатури. Визначити, в якому із рядків файлу найбільша кількість голосних букв. Дописати відповідне повідомлення в кінець файлу з нового рядка.
2.2. Створити для редагування бінарний файл privod.dat, та заповнити його довільними числами (n<=30). Забезпечити підрахунок кількості входжень у файл числа, яке задається із клавіатури. Вивести результат на екран.
2.3. Відкрити для читання текстовий файл, ім’я якого задається з клавіатури. У файлі записано цілі числа через пробіл. Визначити максимальне число у файлі та його порядковий номер, вивести результат на екран.
2.4. Розрахувати значення функції Y=A*sin(B*X) при зміні X від 0 до 2 з кроком 0.01. Значення А та В зчитати з клавіатури. Записати значення функції та аргументу у текстовий файл temp.txt у 2 стовпці із відповідними підписами. Визначити максимальне та мінімальне значення функції, дописати його в кінець файлу. Змінити назву файла на result.txt.
2.5. Розрахувати значення функції Y=С+A*sin(B*X+D) при зміні X від 1 до 3 з кроком 0.1. Значення А, B, C, D зчитати з клавіатури. Записати значення функції у бінарний файл, ім’я якого задається з клавітури. Визначити кількість елементів у файлі.
2.6. Задано текстовий файл epa.txt, в якому записано матрицю цілих чисел розміром 10х10. Визначити суму стовпців матриці та дописати відповідний рядок в кінець файла.
2.7. Задано текстовий файл, ім'я якого задається з клавіатури. Визначити кількість слів у файлі.
2.8. Задано структуру “Студент”, що містить поля “Прізвище”, “Середня оцінка”. Створити базу даних із 3 студентів та записати у бінарний файл, ім'я якого задається з клавіатури. Знайти у файловій базі даних студентів, середній бал яких більший, ніж заданий.
2.9. Задано структуру “Ноутбук”, що містить поля “Ціна”, “Час автономної роботи”. Створити базу даних із 4 ноутбуків та записати у бінарний файл, ім'я якого задається з клавіатури. Знайти у файловій базі даних ноутбук, час автономної роботи якого більший заданного, а ціна мінімальна.
2.10. Створити бінарний файл, ім’я якого задається з клавіатури. Заповнити його дійсними числами (n<=20). Зчитати 5 останніх чисел у файлі, та впорядкувати їх за зростанням. Дописати їх в кінець файлу. Вивести вміст файла на екран.
3. КОНТРОЛЬНІ ЗАПИТАННЯ
3.1. Які функції слугують для форматованого введення-виведення даних у файл.
3.2. Яка функція застосовується для відкривання файлу.
3.3. Чим відрізняється режим редагування від інших режимів відкривання файлів.
3.4. Які функції слугують для редагування бінарних файлів.
3.5. Яким чином можна визначити позицію вказівника у файлі.
3.6. Які функції слугують для посимвольного введення-виведення.
Комп’ютерний практикум № 16
РОБОТА З ФУНКЦІЯМИ НА МОВІ “СІ”
Мета практикуму-вивчення способів декларування функцій та та передачі в програму аргументів командного рядка на мові “СІ”.
1. ТЕОРЕТИЧНІ ВІДОМОСТІ
1.1. Застосування функцій зручне у випадку, коли необхідно виконати деяку кількість однотипних операцій, вони дозволяють значно підвищити ефективність програмування. Функції можна уявити собі як підпрограми. Функція складається із оголошення та тіла функції.
Оголошення функції здійснюється наступним чином
тип_функції назва_функції(тип1 параметр1, ..., тип_n параметр_n);
Наприклад, оголошення функції f, яка повертає ціле значення, та має два цілі аргументи a та b, має вигляд:
int f(int a, int b);
Тіло функції знаходиться відразу після оголошення, та виділяється фігурними дужками {}. Тіло функції може містити ключове слово return, яке служить для повернення результату роботи функції в основну програму після її виконання, наприклад
return <вираз>;
Приклад 1. Зчитати з клавіатури рядок символів та вивести його на екран в зворотному напрямку. Виділити у рядку цифри та вивести їх окремим рядком.
#include <stdio.h>
#include <string.h>
/*Включення файлу з функцією strlen - визначення довжини рядка символів*/
int revers(char s[50]);
/*Оголошення функції revers - розвороту рядка*/
{int i,j,c;
for(i=0, j=strlen(s)-1; i<j; i++, j--)
{c=s[i]; s[i]=s[j]; s[j]=c;}
return(0);}
int cc(char s[], char sn[]);
/*Оголошення функції сс - пошуку цифр у рядку*/
{int i,k=0;
for(i=0;i<strlen(s);i++)
{if (s[i]>='0'&&s[i]<='9')
sn[k++]=s[i];}
sn[k]='\0';
return(0);
}
main()
{char s[50],sn[50];
puts("\n\nInput string");
/*Введіть рядок*/
do {scanf("%s",s);
revers(s);
printf("\n%s\n",s);}
while(s[0]=='0');
/* Цикл виконується до того часу поки не введено 0 */
cc(s,sn);
printf("\nNumerical symbols in the string are- %s",sn);
}
Приклад 2. Вивести масив цілих чисел на екран. При цьому продемонструвати передачу масиву до функції друку через функцію.
#include <stdio.h>
void display(int num[10]);
{
int i;
for(i=0;i<10;i++) printf("%d",num[i]);
}
int main(void)
{int t[10], i;
for(i=0;i<10;i++) t[i]=i;
display(t);
return 0;
}
Необхідно пам’ятати, що при виклику функції в якості її аргументів передаються копії змінних. Тому якщо всередині функції необхідно змінити змінні, які оголошені у основній програмі, їй необхідно передавати вказівники на відповідні змінні.
Приклад 3. Створити функцію, яка міняє місцями значення двох цілих чисел.
#include <stdio.h>
void swap(int *a, int *b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
};
void main(void)
{
int num1, num2;
printf("\n\nEnter two integers ");
scanf("%d %d",&num1,&num2);
swap(&num1,&num2);
printf("Swapped integers are %d %d",num1,num2);
getch();
}
Продемонструємо роботу із числовим масивом як із вказівником:
void display(int num[])
{int i;
for(i=0;i<10;i++) printf("%d",num[i]);
}
Тут аргумент num оголошений як цілочисельний масив невідомого розміру. Оскільки С не перевіряє межі масиву, дійсний розмір масиву не має ніякого відношення до параметру.
При оголошенні аргумента як вказівника функція має вигляд:
void display(int *num)
{int i;
for(i=0;i<10;i++) printf("%d",num[i]);
}
Основна програма main() також є функцією, і може повертати деяке значення в операційну систему після закінчення роботи. Зазвичай приймається, що в разі успішного виконання програма повертає 0.
1.2. Використання рекурсивних функцій. Функція є рекурсивною, якщо вона викликає сама себе. Розглянемо приклад.
Приклад 4. Обчислити значення факторіала n!, використовуючи рекурсивну функцію.
#include <stdio.h>
int factr(int n)
/*Опис функції обчислення факторіала з рекурсією*/
{int answer;
if (n==1) return 1;
answer=factr(n-1)*n;
return answer;
}
main()
{
int k=5;
printf("\nn!=%d",factr(k));
}
1.3. У мові “CI” передбачене передавання програмі аргументів із командного рядка:
int main(int argc, char *argv)
У параметрі argc вказується кількість параметрів, *argv є вказівником на масив символьних рядків-аргументів програми. За згодою, параметр argv[0] містить ім’я програми, тому завжди argc>=1. Крім того, після вказівника на останній рядковий аргумент знаходиться порожній вказівник:
argv[argc]=NULL
При відлагодженні програми параметри командного рядка програми у середовищі TURBO C задаються у меню Run/Arguments….
Приклад 5. Створити функцію, яка знаходить кількість пробілів у текстових файлах. Імена файлів задаються у командному рядку програми.
#include <stdio.h>
#include <conio.h>
int numspace(char *fname)
{
FILE *pfile;
int c,cnt=0;
pfile=fopen(fname,"r");
while((c=getc(pfile))!=EOF)
if(c==' ')cnt++;
close(pfile);
return cnt;
}
void main(int argc, char *argv[])
{
int i;
clrscr();
for(i=1;i<argc;i++)
{
printf("Number of spaces in file %s is %d\n\n",argv[i],numspace(argv[i]));
}
getch();
}
Приклад 6. Переробити попередню програму, розглядаючи argv як вказівник.
#include <stdio.h>
#include <conio.h>
int numspace(char *fname)
{
FILE *pfile;
int c,cnt=0;
pfile=fopen(fname,"r");
while((c=getc(pfile))!=EOF)
if(c==' ')cnt++;
close(pfile);
return cnt;
}
void main(int argc, char *argv[])
{
clrscr();
while(argc-->1)
{
argv++;
printf("Number of spaces in file %s is %d\n\n",*argv,numspace(*argv));
}
getch();
}
2. ЗАВДАННЯ НА РОБОТУ
Розробити та запустити у роботу програму на мові програмування “СІ”, яка вирішує задачу відповідно до заданого нижче варіанта.
2.1. Створити рекурсивну функцію для розрахунку n – го члена послідовності Фібоначчі F0=F1=0, Fn+2=Fn+1+Fn , n<=10. Результат зберегти у файл. Номер члена послідовності та ім’я файла задаються як аргументи командного рядка програми.
2.2. Створити функцію для розрахунку кількості дійсних коренів квадратного рівняння AX2+BX+C=0. Значення коефіцієнтів А, B, C задаються як аргументи командного рядка програми.
2.3. Створити програму на основі функції для знаходження максимального серед чисел, які знаходяться в текстовому файлі. Ім’я файла задається як аргумент командного рядка програми.
2.4. Створити функцію, яка підраховує кількість символів у текстовому файлі. Ім’я файла задається як аргумент командного рядка програми.
2.5. Створити функцію, що повертає кількість голосних букв у рядку. Рядок задається як аргумент командного рядка програми.
2.6. Створити функцію, яка вказує, чи проходить пряма AX+BY+C=0 через початок координат. Продемонструвати роботу функції. Значення коефіцієнтів А, B, C задаються як аргументи командного рядка програми.
2.7. Створити функцію для копіювання файла. Імена вихідного та результуючого файлів задаються як аргументи командного рядка програми.
2.8. Створити функцію, яка вказує, чи знаходиться деяка точка B з координатами (xb;yb) всередині прямокутника з вершинами A (xa;ya) та C(xc;yc). Координати точок задаються як аргументи командного рядка програми.
2.9. Створити функцію, яка вказує, чи знаходиться деяка точка D з координатами (xd;yd) всередині трикутника з вершинами A (xa;ya), B (xb;yb) та C(xc;yc). Координати точок задаються як аргументи командного рядка програми.
2.10. Створити функцію, яка вказує, чи паралельні дві прямі AX+BY+C=0таA1X+B1Y+C1=0. Коефіцієнти прямих задаються як аргументи командного рядка програми. Результат записується на екран та у текстовий файл, ім’я якого також задається як аргумент командного рядка програми.
3. КОНТРОЛЬНІ ЗАПИТАННЯ