1. Датотеки
1.1. Потсетување од предавања
-
Обработката на датотеки се состои од запишување, вчитување или менување на содржината на датотека зачувана на некој стандарден медиум како хард диск.
-
Обработката на датотеки во програмскиот јазик C се прави со помош на структурата
FILE
, дефинирана воstdio.h
. -
За да се започне со обработка на датотеката, прво мора да се отвори истата со помош на функцијата
fopen()
, која како резултат враќа покажувач кон структураFILE*
.
1.1.1. Отворање на датотека за читање/запишување
Функција за отворање на датотека:
FILE* fopen(const char* ime_datoteka, const char* mod);
ime_datoteka
- целосната патека каде е зачувана датотеката која сакаме да ја отвориме, заедно со името на датотеката
mod
- начин на отворање на датотеката
-
Можните начини на отворање на дадена датотека (можни вредности за вториот аргумент
mod
на функцијатаfopen()
) се дадени во продолжение.
Начин | Значење |
---|---|
|
Отвора постоечка датотека само за читање |
|
Отвора (создава) нова датотека за запишување (ако датотеката веќе постои - ќе ја пребрише нејзината содржина) |
|
Отвора датотека за додавање содржина на крајот од датотеката (ако датотеката не постои - ќе се креира) |
|
Отвора постоечка датотека за читање и запишување од почетокот на датотеката |
|
Отвора (создава) нова датотека за читање и запишување (ако датотеката веќе постои - ќе ја пребрише нејзината содржина) |
|
Отвора датотека за читање и за додавање содржина на крајот од датотеката (ако датотеката не постои - ќе се креира) |
FILE* fp = fopen("test.txt", "r");
-
Се отвора текстуалната датотека "test.txt" во режим за читање.
-
За да се отвори датотеката во бинарен мод, се додава буквата
b
на крајот на аргументот за начинот на отворање (пр."rb"
).
1.1.2. Затворање на датотека
Функција за затворање на датотека:
int fclose(FILE* fp);
fp
- покажувач асоциран на датотеката што сакаме да ја затвориме
fclose(fp);
-
По завршување со работа со датотеката, таа треба да се затвори со помош на функцијата
fclose()
-
Со оваа функција се затвора датотеката на која што во моментот е асоциран покажувачот
fp
што се предава како аргумент на функцијата
1.1.3. Читање и запишување од/во датотека
Функции за читање од датотека:
int fscanf(FILE* fp, "kontrolna niza", lista_na_argumenti);
int fgetc(FILE* fp);
char* fgets(char* str, int num, FILE* fp);
Функции за запишување во датотека:
int fprintf(FILE* fp, "kontrolna niza", lista_na_argumenti);
int fputc(char c, FILE* fp);
int fputs(const char* str, FILE* fp);
---
1.2. Задача 1
Да се напише програма која за дадена текстуална датотека text.txt
ќе го одреди и отпечати на екран односот на самогласките и согласките.
Ако датотеката text.txt
ја има следнава содржина:
Zdravo, kako si? Eve, dobro sum. A ti? I jas dobro.
тогаш програмата треба да отпечати:
Odnos samoglaski/soglaski: 16/19 = 0.84
p11_1.c
#include <stdio.h>
int e_bukva(char c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}
int e_samoglaska(char c) {
c = tolower(c);
switch (c) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
return 1;
default:
return 0;
}
}
int main() {
char c;
int soglaski = 0, samoglaski = 0;
FILE *dat;
// Otvoranje na datoteka za chitanje
if ((dat = fopen("text.txt", "r")) == NULL) {
printf("Datotekata text.txt ne mozhe da se otvori.\n");
return -1;
}
// Chitanje znak po znak se' dodeka ne se prochita EndOfFile (EOF)
while ((c = fgetc(dat)) != EOF) {
if (e_bukva(c)) {
if (e_samoglaska(c))
samoglaski++;
else
soglaski++;
}
}
fclose(dat);
printf("Odnos samoglaski/soglaski: %d/%d = %5.2f\n", samoglaski, soglaski,
(float) samoglaski / soglaski);
return 0;
}
1.3. Задача 2
Да се напише програма која секој ред од дадена текстуална датотека vlezna.txt
ќе го копира во друга датотека izlezna.txt
, така што пред секој прочитан ред од датотеката vlezna.txt
ќе додаде уште еден ред во кој ќе стои бројот на знаци што ги содржи прочитаниот ред.
Во секој ред може да има најмногу 80 знаци.
Ако датотеката vlezna.txt
ја има следнава содржина:
Jas ucham Strukturno Programiranje. Koga se polaga vtoriot kolokvium? Ne znam, seushte ne e objaveno na sajtot.
тогаш по извршувањето на програмата содржината на датотеката izlezna.txt
треба да биде следнава:
36 Jas ucham Strukturno Programiranje. 34 Koga se polaga vtoriot kolokvium? 41 Ne znam, seushte ne e objaveno na sajtot.
p11_2.c
#include <stdio.h>
#define MAX 81
int main() {
char linija[MAX], *c;
FILE *vlezna, *izlezna;
if ((vlezna = fopen("vlezna.txt", "r")) == NULL) {
printf("Datotekata %s ne mozhe da se otvori.\n", "vlezna.txt");
return -1;
}
if ((izlezna = fopen("izlezna.txt", "w")) == NULL) {
printf("Datotekata %s ne mozhe da se otvori.\n", "izlezna.txt");
return -1;
}
while ((fgets(linija, MAX, vlezna)) != NULL) {
int br = strlen(linija);
fprintf(izlezna, "%d\n%s", br, linija);
}
fclose(vlezna);
fclose(izlezna);
return 0;
}
1.4. Задача 3
Да се напише програма која ќе ги прочита елементите од една матрица сместена во текстуална датотека matrica1.txt
. Во првиот ред од датотеката се запишани бројот на редици и бројот на колони на матрицата. Секој елемент од матрицата е реален број запишан во посебен ред од датотеката.
Потоа матрицата треба да се транспонира и да се запише во нова датотека matrica2.txt
на истиот начин.
Ако датотеката matrica1.txt
ја има следнава содржина:
3 4 2.1 3.2 4.3 5.4 1.1 2.2 3.3 4.4 6.0 5.5 3.9 1.8
тогаш по извршувањето на програмата содржината на датотеката matrica2.txt
треба да биде следнава:
4 3 2.1 1.1 6.0 3.2 2.2 5.5 4.3 3.3 3.9 5.4 4.4 1.8
p11_3.c
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
int main() {
int i, j, m, n;
float a[MAX][MAX], b[MAX][MAX];
FILE *input, *output;
if ((input = fopen("matrica1.txt", "r")) == NULL) {
printf("Datotekata matrica1.txt ne se otvora!\n");
exit(1);
}
if (!feof(input))
fscanf(input, "%d %d", &m, &n);
if ((m > MAX) || (n > MAX)) {
printf("Mnogu golema matrica!");
return (-1);
}
for (i = 0; i < m && !feof(input); i++)
for (j = 0; j < n && !feof(input); j++)
fscanf(input, "%f", &a[i][j]);
fclose(input);
if (i != m || j != n) {
printf("Nema dovolno podatoci vo datotekata!");
return (-1);
}
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
b[j][i] = a[i][j];
if ((output = fopen("matrica2.txt", "w")) == NULL) {
printf("Datotekata matrica2.txt ne se otvora!\n");
exit(1);
}
fprintf(output, "%d %d\n", n, m); /* obratno */
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
fprintf(output, "%7.2f\n", b[i][j]);
fclose(output);
return (0);
}
1.5. Задача 4
Дадена е текстуална датотека SP_primer.txt
. Да се напише програма која ќе ја прочита датотеката и на екран ќе го отпечати бројот на редови во кои има повеќе од 10 самогласки, како и вкупниот број на самогласки во датотеката.
Ако датотеката SP_primer.txt
ја има следнава содржина:
Zdravo, kako si? Eve, dobro sum. A ti? I jas dobro. Kako se tvoite? Ima li neshto novo? Dobri se i tie. Si kupiv avtomobil.
тогаш програмата треба да отпечати:
Vkupno 2 reda imaat povekje od 10 samoglaski. Vo datotekata ima vkupno 42 samoglaski.
p11_4.c
#include <stdio.h>
#include <stdlib.h>
int e_samoglaska(char c) {
return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
}
int main() {
int red = 0, vkupno = 0;
FILE *dat; char c;
if ((dat = fopen("SP_primer.txt", "r")) == NULL) {
printf("Datotekata SP_primer.txt ne se otvora");
exit(-1);
}
int samoglaski = 0;
while ((c = fgetc(dat)) != EOF) {
if(e_samoglaska(tolower(c))) {
++samoglaski;
++vkupno;
}
if (c == '\n') {
if (samoglaski > 10) {
red++;
}
samoglaski = 0;
}
}
if (samoglaski > 10) {
red++;
}
printf("Vkupno %d reda imaat povekje od 10 samoglaski\n", red);
printf("Vo datotekata ima vkupno %d samoglaski.\n", vkupno);
return 0;
}
1.6. Задача 5
Да се напише програма која за дадена текстуална датотека zborovi.txt
ќе ги отпечати на екран сите зборови во кои се појавуваат повеќе од две исти букви (некоја буква се појавува три или повеќе пати). Да не се прави разлика помеѓу мали и големи букви. На крајот треба да се отпечати и бројот на зборови што го задоволуваат условот.
Секој ред во датотеката содржи по еден збор (зборовите се разделени меѓу себе со знак за нов ред). Секој збор е составен само од букви. Максималната должина на зборовите е 20 знаци.
Ако датотеката zborovi.txt
ја има следнава содржина:
banana jabolko Obratnoto binarnata dekadniot Kopakabana
тогаш програмата треба да отпечати:
banana Obratnoto binarnata Kopakabana Vkupno 4 zborovi.
p11_5.c
#include <stdio.h>
#include <ctype.h>
#define DOLZINA 21
int ima_poveke_od2isti(char *w) {
char *c;
int isti;
while (*w) {
c = w + 1;
isti = 1;
while (*c) {
if (tolower(*w) == tolower(*c))
isti++;
c++;
}
if (isti > 2)
return 1;
w++;
}
return 0;
}
int main() {
char zbor[DOLZINA];
FILE *f;
int brzb = 0;
if ((f = fopen("zborovi.txt", "r")) == NULL) {
printf("Datotekata %s ne se otvora.\n", "zborovi.txt");
return -1;
}
while (fgets(zbor, DOLZINA, f) != NULL) {
if (ima_poveke_od2isti(zbor)) {
puts(zbor);
brzb++;
}
}
printf("\nVkupno %d zborovi.\n", brzb);
fclose(f);
return 0;
}
1.7. Задача 6
Да се напише програма која на екран ќе го отпечати бројот на појавувања на даден збор составен само од цифри (зборот се чита од тастатура) во текстуална датотека со име dat.txt
.
Ако од тастатура се внесе зборот
123
и ако датотеката dat.txt
ја има следнава содржина:
Zdravo 123, kako si? Eve 321, dobro sum. A ti? I jas dobro. Kako se tvoite 123? Ima li neshto novo? 123 Dobri se i tie. Si kupiv avtomobil.
тогаш програмата треба да отпечати:
Zborot 123 se pojavuva 3 pati vo datotekata.
p11_6.c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main() {
char c;
int brPojavuvanja = 0;
FILE *dat;
if ((dat = fopen("dat.txt", "r")) == NULL) {
printf("Datotekata %s ne se otvora!\n", "dat.txt");
exit(-1);
}
char zbor[50];
printf("Vnesete zbor za koj kje se bara brojot na pojavuvanja:");
gets(zbor);
int i = 0, br = 0;
while ((c = fgetc(dat)) != EOF) {
if (isdigit(c)) {
if (c != zbor[i++]) {
if (br == strlen(zbor)) {
brPojavuvanja++;
}
br = 0;
i = 0;
} else {
br++;
}
} else {
if (br == strlen(zbor)) {
brPojavuvanja++;
}
br = 0;
i = 0;
}
}
printf("Zborot %s se pojavuva %d pati vo datotekata\n", zbor,
brPojavuvanja);
return 0;
}