Zo SS:
lubbo7 napísal:tak otazok bude viac,zoberiem to postupne:
Kód: Vybrať všetko
int zapisPole(size_t dlzka, Element pole[], const char *cestaKSuboru) {//preco element pole? ja som pouzil float pole a islo mi to
Toto ma suvis s definiciou vyssie:
Klucove slovo
typedef umoznuje nejakemu typu pridat 'alias'. V nasom pripade to znamena, ze vsade tam, kde si doteraz pisal
float mozes napisat
Element. Je to cosi podobne, ako keby si napisal:
Az na to, ze ten
typedef je cistejsi nez je
#define (okrem ineho). Vyhoda je, ze keby si sa rozhodol pouzit iny typ (napriklad ten spominany
double), staci Ti zmenit riadok s
typedef t.j. je to na jednom mieste.
Okrem toho sa
typedef pouziva na zprehladnenie deklaracii; priklad z kodu:
Kód: Vybrať všetko
typedef size_t (*Triedic)(size_t dlzka, Element pole[]);
Toto definuje novy typ
Triedic ktory oznacuje ukazatel na funkciu, berucu dva parametre, a vracajucu
size_t. To je uz ale mimo Tvoju povodnu otazku; tento novy typ sa navyse pouziva v kode, ktory pre Tvoje ucely nepotrebujes.
V skratke: ak vies, ze chces len floaty, tak
Element nepotrebujes. Za toto sa ospravedlnujem - je to sice pomerne dolezite, ale nieje to nevyhnutne, a mal som si uvedomit ze privela novych veci zabije aj slona.
Kód: Vybrať všetko
FILE *subor = fopen(cestaKSuboru, "wb+"); // 1. riadok
size_t zapisanyPocetElementov; // tomuto vobec nerozumiem,co sa v tomto kroku vykona
if (!subor){ // 3-ti riadok
perror("Zlyhalo otvorenie suboru na zapis"); // 4.
return 0; // 5.
}
Toz: V prvom riadku sa zavola fcia
fopen, pomocou ktorej sa otvori subor ktoreho cestu udava obsah premennej
cestaKSuboru (retazec) na zapis (lebo
"w").
V dalsom riadku je len deklaracia novej premennej s nazvom
zapisanyPocetElementov, typu
size_t. Tento typ sa pouziva pre premenne oznacujuce pocet, alebo dlzku - standard garantuje, ze sa do neho zmesti aspon take cislo, kolko byteov moze mat najvacsi objekt.
Treti riadok je ekvivalentny tomuto:
Premenna
subor bude 0 (t.j.
NULL) len ak zlyha volanie funkcie
fopen z prveho riadku.
Stvrty a piaty riadok sa teda vykonaju len ak sa nepodari otvorit subor. Riadok s funkciou
perror je
+- ekvivalentny tomuto:
Kód: Vybrať všetko
fprintf(stderr, "Zlyhalo otvorenie suboru na zapis: %s\n", strerror(errno));
Toto volanie fcie
fprintf zapise do 'suboru'
stderr formatovany retazec; vysledkom konstruktu
strerror(errno) je retazec popisujuci chybu (kedze sa nepodarilo otvorit subor).
stderr oznacuje tzv.
standardny chybovy vystup. Je to subor do ktoreho sa da zapisovat; pri spusteni programu v konzole sa vsetko zapisane do
stderr vypise aj na konzolu t.j. pouzivatel uvidi chybovu hlasku. Existuje aj
stdout; rozdiel medzi nimi dvoma je v tom, ze do toho prveho by sa mali zapisovat chybove hlasky, a do druheho hlasky o priebehu - ked napises:
tak v skutocnosti sa zavola:
Kód: Vybrať všetko
zapisanyPocetElementov = fwrite(pole, sizeof(Element), dlzka, subor);//preco je tento prikaz priradovany premennej a nieje to len cast napravo od =?
Funkcia
fwrite vracia pocet zapisanych elementov. Riadky nizsie overia, ci je tento pocet zhodny s poctom ktory sme naozaj chceli zapisat (t.j.
dlzka). Vacsi asi nebude, ale moze byt mensi, napriklad ked dojde miesto, alebo sa zapis z nejakeho dovodu prerusi atd.
Je dobrou praxou overovat taketo veci, pretoze shit happens, a cim skor ho odchytis, tym menej sa dostane k ventilatoru.
Kód: Vybrať všetko
fclose(subor);
if (zapisanyPocetElementov != dlzka) {
fprintf(stderr, "Nepodarilo sa zapisat do suboru '%s'.\n", cestaKSuboru);// k comu je stderr?
return 0;
}
return 1;
}
Na prvom riadku sa uzavrie subor, kedze sme do neho uz svoje zapisali. Je dobrou praxou uvolnovat prostriedky hned ako sa da (to sa tyka pamate, suborov, zamkov, .. vsetkeho). V pripade suboru by sa dokonca mohlo stat, ze sa do neho nezapisu vsetky data, kym sa nezavrie (alebo kym ho tzv.
nesplachnes).
Dalsie riadky kontroluju pocet zapisanych elementov.
Tolko v jednom prispevku, zvysok si radsej necham na zajtra
War is peace. Freedom is slavery. Ignorance is strength.
There is no such thing as a well-adjusted slave.