Práca so súbormi
Maximum z nameraných teplôt
V textovom súbore sa nachádza 10 teplôt (reálne čísla). Nájdite najväčšiu nameranú teplotu.
Na I/O operácie použijeme:
fopen()
na otvorenie súboru v režime čítania (r
).- funkcia vracia
FILE *
(čítaj smerník na FILE, resp. pointer na FILE, resp. ukazovateľ na FILE)FILE
je veľkými písmenami!
- výnimky v C neexistujú. Chyba sa indikuje návratovou hodnotou. Po dobehnutí funkcie je nutné overiť, že návratová hodnota nie je
NULL
- na rozdiel od Javy je
NULL
konštanta uvádzaná veľkými písmenami. - ak sa súbor nenájde, program môžeme rovno ukončiť. Vráťme nenulovú hodnotu, napr. -1.
- na rozdiel od Javy je
- funkcia vracia
prípadnú chybu môžeme vypísať cez
perror()
. Tá vypíše nielen vlastnú hlášku, ale aj popisnejšiu hlášku pochádzajúcu zo systému.fclose()
slúži na zavretie súboru.
Vyskúšajme si minimalistickú verziu, so zámerne zlou cestou k súboru:
#include<stdio.h>
int main() {
FILE * subor;
subor = fopen("neexistujuci.txt", "r");
if(subor == NULL) {
perror("Subor sa nepodarilo otvorit");
return -1;
}
fclose(subor);
return 0;
}
Na načítavanie:
fscanf()
je použité na načítanie hodnoty.- syntax je podobná
printf()
: formátovací reťazec nasledovaný premennými - hodnoty typu
double
načítavame cez špecifikátor%lf
(long float) - pri načítavaní cez scan označíme premenné prefixom
&
. Súvisí to so smerníkmi, o ktorých nevieme nič.
- syntax je podobná
Maximum môžeme inicializovať konštantou INT_MIN
z hlavičkového súboru limits.h
.
- Nezabudnime
include
-núť príslušný súbor!
Celý zdroják:
#include<stdio.h>
#include<limits.h>
#define POCET_HODNOT 10
int main() {
double maximum = INT_MIN;
double hodnota = 0;
int i = 0;
FILE * subor;
subor = fopen("teploty.txt", "r");
if(subor == NULL) {
perror("Subor sa nepodarilo otvorit");
return -1;
}
for(i = 0; i < POCET_HODNOT; i++) {
fscanf(subor, "%lf", &hodnota);
if(hodnota > maximum) {
maximum = hodnota;
}
}
printf("Maximum je: %f", maximum);
fclose(subor);
return 0;
}
Maximum z nameraných teplôt [cez pole]
Načítajte 10 teplotných hodnôt do poľa. Nájdite v ňom maximum.
Úloha je rozšírením predošlého zadania.
pole 10 prvkov deklarujeme cez:
double prvky[POCET_PRVKOV]
Porov. s Javou:
/*Java:*/ double[] prvky = new double[POCET_PRVKOV];
pole v C možno nadeklarovať (bez inicializácie prvkami) len na základe konštanty. Pri uvádzaní dĺžky poľa nemožno použiť premennú! (Vysvetlenie napríklad v 5. dieli seriálu o Jave.)
môžeme radostne načítavať
fscanf()
om do prvku poľa. Nezabudnime na ampersand!fscanf(subor, "%lf", &prvky[i]);
ak vytvárame funkciu, ktorá berie pole, vždy dodajme argument s dĺžkou poľa!
- v C nemožno za behu zistiť dĺžku poľa, na rozdiel od Javy, kde existuje
prvky.length
.
- v C nemožno za behu zistiť dĺžku poľa, na rozdiel od Javy, kde existuje
Celý zdroják
#include<stdio.h>
#include<limits.h>
#define POCET_PRVKOV 10
double najdi_maximum(double prvky[], int dlzka) {
int i = 0;
double maximum = INT_MIN;
while(i < dlzka) {
if(prvky[i] > maximum) {
maximum = prvky[i];
}
i++;
}
return maximum;
}
int main() {
FILE * subor;
int i = 0;
double prvky[POCET_PRVKOV];
subor = fopen("teploty.txt", "r");
if(subor == NULL) {
perror("Subor sa nepodarilo otvorit");
return -1;
}
for(i = 0; i < POCET_PRVKOV; i++) {
fscanf(subor, "%lf", &prvky[i]);
}
printf("Maximum je: %f", najdi_maximum(prvky, POCET_PRVKOV));
fclose(subor);
return 0;
}
Poznámky
Nastavte si nano
- Skratkou
Ctrl + _
(podtržidlo) môžete prechádzať na zadané číslo riadku. Ak spustíte
nano
s parametrom-c
, dostanete stavový riadok s číslom aktuálneho riadka v súborenano -c teploty2.c
Toto nastavenie môžete zaviesť do konfiguráku
nano
:nano ~/.nanorc
Uveďte doň jediný riadok:
set const
Odteraz nemusíte používať parameter
-c
.
Generovanie náhodných čísiel
Teploty možno nagenerovať v shelli cez seq
a awk
:
seq 10 | awk 'BEGIN { srand() } { printf "%.2f\n", -(rand() * 60) - 30}'
- Vygenerujeme 10 náhodných čísiel.
- Pred spracovávaním prvého nainicializujeme generátor čísiel.
V
awk
vracia funkciarand()
reálne číslo medzi 0 a 1. Využijeme vzorec:spodok + číslo * (vrch - spodok) -30 + číslo * (30 - -30) -30 + číslo * 60
Vytlačíme ho s presnosťou na dve desatinné miesta —
printf()
funguje presne ako v C.