ZER DAKIDAN: Fitxategiak zer diren badakit, eta fitxategiak irekitzeko w, r eta a markak erabili behar ditudala badakit. ZER IKASIKO DUDAN: FILE datu-motarekin jarraituz, elementu baten datua aldatzen ikasiko dut, urratsak hiru dira:
|
Datuak gordetzen dituen fitxategi bat daukagu. Esate baterako, estrukturen fitxategi bat daukagu eta gako bat eman ondoren (adibidez Danel izena) izen horretako elementuari bere fNota eremuaren balioa aldatu nahi zaio. Elementuaren liPosizioa() posizioa ezaguna izanik, dagokion izeneko ikaslearen nota aldatuko zaio. Horretarako:
... fseek(f, liPosizioa*(long)sizeof(struct tstFitxa), SEEK_SET); // elementaren gainean kokatu fread(&stElem, sizeof(struct tstFitxa), 1, f); // elementua irakurri
printf("Nota zaharra: %8.2f\n", tsElem.fNota); // nota ikusi printf("Nota berria eman: "); // nota berria eman scanf("%f", &tsElem.fNota); fseek(f, liPosizioa*(long)sizeof(struct tstFitxa), SEEK_SET); // elementaren gainean kokatu
// fseek(f, (-1)*(long)sizeof(struct tstFitxa), SEEK_CUR); // dagoen tokitik posizio bat atzera
fwrite(&tsElem, sizeof(struct tstFitxa), 1, f); // elementua idatzi
...
Erakusten den programa honetan fitxategiaren existentzia frogatzen da programa nagusian, horren arabera:
- Baldin eta fitxategia bada elementu baten aldaketa burutuko da
- Fitxategirik ez bada, programa amaitu aurretik mezu batez adierazten da
Fitxategirik bada, lehenik eta behin Danel izeneko ikaslerik ote dagoen frogatuko da bilaketa bat eginez, gogoratu Ariketa 79 | Bilaketa: 4. algoritmoa adibidea non liIzenaBilatu() funtzioak elementuaren liPosizioa posizioa itzultzen duen. Baiezkoan, elementua aurkitzean, Danel izeneko ikasleren nota aldatuko zaio, horretarako:
- Zehaztutako fitxategiaren edukia pantailaratu
- Izen bat teklatuz irakurri eta fitxategian bilatzen da bere nota aldatzeko, egoera bi hauek aintzat hartzen dira:
- Gakoa den izena ez da aurkitzen fitxategian, mezu bat pantailaratzen da
- Gakoa den izena fitxategian aurkitzen da:
- Elementu horren datuak pantailaratzen dira
- Programak nota berria eskatuko du aldaketa burutzeko
- Aldaketa gauzatzen da
- Fitxategi berrituaren edukia pantailaratzen da
/* Ariketa-80_Fitxategien_5a_algoritmoa: elementu bat aldatu fitxategian */ // Datu-fitxategiaren existentzia frogatzen da funtzio nagusiko hasieran // propio idatzi den iFitxategirikBada() funtzioari esker. // Suposatuz aldatuko den elementua zein den dakigula, elementua zehazteko // bere eremuko datu bat ematen da teklatuz: sIzenDeiturak eremuko datua. // Bilatzen ari den gakoa aurkitzean, elementuaren posizioa fitxategian // itzuliko da: liPosizioa = ftell(f) / sizeof(struct tstFitxa) - 1; // Bestela, aurkitzen ez bada, -1 marka itzuliko du bilaketaren funtzioak. // Aldaketa gauzatzeko fseek() funtzioan oinarrituko gara, bai irakurtzeko eta // bai idazteko: fseek(f, liPosizioa*(long)sizeof(struct tstFitxa), SEEK_SET); #include <stdio.h> #include <string.h> // strcpy() eta strcmp() funtzioetarako #include <conio.h> // getch() funtziorako #define sBIDEA "C:\\Tokia\\" #define FITX_IZEN_MAX 120 // fitxategiaren izenerako 119 karaktere gehi null mugatzailea #define DATU_IZEN_MAX 72 // ikaslearen izena gordetzeko 71 karaktere gehi null mugatzailea struct tstFitxa // datu-motaren definizioa { char sIzenDeiturak[DATU_IZEN_MAX]; int iDeialdia; float fNota; }; int iFitxategirikBada(const char sFitxIzen[]); void DatuGuztiakErakutsi(const char sFitxIzen[]); long liBilaketa(const char sFitxIzen[], const char *sGakoa); void DagoenaIkusi(const struct tstFitxa stElem); void DatuaBildu(struct tstFitxa *stElem); void Aldaketa(const char sFitxIzen[], long liPosizioa); int main() { char sFitxIzenLaburra[FITX_IZEN_MAX]; char sFitxIzen[FITX_IZEN_MAX]; char sGakoa[DATU_IZEN_MAX]; long liPosizioa; printf("Fitxategia existitzen da eta datuak ditu\n(adibidez C:\\Tokia\\Ikasleak.DAT)\n\n"); printf("Fitxategiaren izen laburra eman (adibidez 'Ikasleak'): "); scanf("%s", sFitxIzenLaburra); getchar(); // Enter karakterea kentzeko strcpy(sFitxIzen, "C:\\Tokia\\"); strcat(sFitxIzen, sFitxIzenLaburra); strcat(sFitxIzen, ".dat"); if (iFitxategirikBada(sFitxIzen) == 1) { printf("\n"); DatuGuztiakErakutsi(sFitxIzen); printf("\n"); printf("Nota aldatu nahi zaion ikaslearen izen deiturak eman: "); gets(sGakoa); liPosizioa = liBilaketa(sFitxIzen, sGakoa); if (liPosizioa == -1) printf("'%s' izeneko ikaslerik ez dago %s fitxategian\n", sGakoa, sFitxIzen); else { Aldaketa(sFitxIzen, liPosizioa); printf("\n"); DatuGuztiakErakutsi(sFitxIzen); } } else printf("'%s' fitxategia ez da existitzen, agur...", sFitxIzen); printf("\nPrograma bukatzera doa. Edozein tekla sakatu! "); getch(); // itxaron edozein tekla sakatu arte printf("\n"); return 0; } // Funtzio honek fitxategi baten existentzia frogatzen du. int iFitxategirikBada(const char sFitxIzen[]) { FILE *f; // Irakurketarako irekitze saiakera ("r" = read) f = fopen(sFitxIzen, "rb"); // Fitxategirik ez balego fopen() funtzioak NULL itzuliko luke if (f != NULL) { fclose(f); // fitxategia itxi baliabidwak askatzeko return 1; // Itzuli 1 (true): fitxategia bada } // Fitxategirik ez balego fopen() funtzioak NULL itzuliko luke return 0; // Itzuli 0 (false): fitxategia ez da existitzen } // fitxategiaren prozesaketa osoa void DatuGuztiakErakutsi(const char sFitxIzen[]) { FILE *f; struct tstFitxa stElem; int iPosizioa; // fitxategi bitarra irakurketa moduan ireki f = fopen(sFitxIzen, "rb"); if (f == NULL) { printf("Errorea '%s' fitxategia irekitzean 'DatuGuztiakErakutsi()' funtzioan \a\n", sFitxIzen); return; } else { // fitxategiko datuak banan-banan irakurri eta pantailan erakutsi iPosizioa = 0; while (fread(&stElem, sizeof(struct tstFitxa), 1, f)) // irakurtzerik dagoen bitartean... { printf("Ikaslea: %-20s Deialdia: %d Nota: %.2f\n", stElem.sIzenDeiturak, stElem.iDeialdia, stElem.fNota); iPosizioa++; } fclose(f); } } // funtzioa: bilaketa fitxategian long liBilaketa(const char sFitxIzen[], const char *sGakoa) { struct tstFitxa stElem; int booAurkitua = 0; long posizioa = -1; FILE *f; f = fopen(sFitxIzen, "rb"); if (f == NULL) { printf("Errorea '%s' fitxategia irekitzean 'liBilaketa()' funtzioan \a\n", sFitxIzen); return -1; } while (fread(&stElem, sizeof(struct tstFitxa), 1, f) == 1 && !booAurkitua) { if (strcmp(stElem.sIzenDeiturak, sGakoa) == 0) { booAurkitua = 1; posizioa = ftell(f) / sizeof(struct tstFitxa) - 1; } } fclose(f); return posizioa; } // dagoena erakutsi, erregistroa balioz igarotzen da eta ez da aldatuko void DagoenaIkusi(const struct tstFitxa stElem) { printf("Ikaslea: %-20s %5d %8.2f\n", stElem.sIzenDeiturak, stElem.iDeialdia, stElem.fNota); } // datua bildu, erregistroa erreferentziaz idarotzen da aldatua izan dadin void DatuaBildu(struct tstFitxa *stElem) { printf("'%s' ikaslearen nota berria eman: ", stElem->sIzenDeiturak); scanf("%f", &stElem->fNota); } // aldaketarako ezaguna da elementuaren posizioa fitxategian void Aldaketa(const char sFitxIzen[], long liPosizioa) { FILE *f ; struct tstFitxa stElem; f = fopen(sFitxIzen, "r+b"); if (f == NULL) { printf("Errorea '%s' fitxategia irekitzean 'Aldaketa()' funtzioan \a\n", sFitxIzen); return; } fseek(f, liPosizioa * sizeof(struct tstFitxa), SEEK_SET); fread(&stElem, sizeof(struct tstFitxa), 1, f); DagoenaIkusi(stElem); DatuaBildu(&stElem); fseek(f, liPosizioa*(long)sizeof(struct tstFitxa), SEEK_SET); // fseek(f, (-1)*(long)sizeof(struct tstFitxa), SEEK_CUR); // dagoen tokitik posizio bat atzera fwrite(&stElem, sizeof(struct tstFitxa), 1, f); fclose(f); }
Erakusten den programa honetan fitxategiaren existentzia frogatzen da programa nagusian, horren arabera:
- Baldin eta fitxategia bada, ondoko bi lanak burutuko dira:
- Zehaztutako fitxategiaren edukia pantailaratu
- Aldatu nahi den elementuaren posizioa teklatuz eman, kontrolaturik ematen den balioa baliagarria dela
- Posizio horretako elementuaren datuak pantailaratzen dira
- Programak nota berria eskatuko du aldaketa burutzeko
- Aldaketa gauzatzen da
- Bukatzeko, fitxategi berrituaren edukia pantailaratu
- Baldin eta fitxategirik ez bada, mezu batez adierazten da
/* Ariketa-80_Fitxategien_5b_algoritmoa: elementu bat aldatu fitxategian */ // Datu-fitxategiaren existentzia frogatzen da funtzio nagusiko hasieran // propio idatzi den iFitxategirikBada() funtzioari esker. // Suposatuz aldatuko den elementuaren posizioa dakigula, bere posizioa // ematen da teklatuz (aldez aurretik fitxategiko elementuen kopurua // kalkulatuko da). 'Ariketa-80_Fitxategien_5a_algoritmoa' kasuan bezala, // aldaketa gauzatzeko fseek() funtzioan oinarrituko gara, bai irakurtzeko // eta bai idazteko, bi modu nondik abiatzen garen arabera: // 1. hasieratik, fseek(f, liPosizioa*(long)sizeof(struct tstFitxa), SEEK_SET); // 2. tokitik 1 atzera, fseek(f, (-1)*(long)sizeof(struct tstFitxa), SEEK_CUR); #include <stdio.h> #include <string.h> // strcpy() eta strcat() funtzioetarako #include <conio.h> // getche() eta getch() funtzioetarako #define sBIDEA "C:\\Tokia\\" #define FITX_IZEN_MAX 120 // fitxategiaren izenerako 119 karaktere gehi null mugatzailea #define DATU_IZEN_MAX 72 // ikaslearen izena gordetzeko 71 karaktere gehi null mugatzailea struct tstFitxa // datu-motaren definizioa { char sIzenDeiturak[DATU_IZEN_MAX]; int iDeialdia; float fNota; }; int iFitxategirikBada(const char sFitxIzen[]); void DatuGuztiakErakutsi(const char sFitxIzen[]); long liZenbatElementu(const char sFitxIzen[]); void DagoenaIkusi(const struct tstFitxa stElem); void DatuaBildu(struct tstFitxa *stElem); void Aldaketa(const char sFitxIzen[], long liPosizioa); int main() { char sFitxIzenLaburra[FITX_IZEN_MAX]; char sFitxIzen[FITX_IZEN_MAX]; long liPosizioa; long liAzkenPosizioa; printf("Fitxategia existitzen da eta datuak ditu\n(adibidez C:\\Tokia\\Ikasleak.DAT)\n\n"); printf("Fitxategiaren izen laburra eman (adibidez 'Ikasleak'): "); scanf("%s", sFitxIzenLaburra); getchar(); // Enter karakterea kentzeko strcpy(sFitxIzen, "C:\\Tokia\\"); strcat(sFitxIzen, sFitxIzenLaburra); strcat(sFitxIzen, ".dat"); if (iFitxategirikBada(sFitxIzen) == 1) { printf("\n"); DatuGuztiakErakutsi(sFitxIzen); printf("\n"); liAzkenPosizioa = liZenbatElementu(sFitxIzen) -1; do { printf("Aldatu nahi den ikaslearen posizioa eman: (0 eta %ld artekoa): ", liAzkenPosizioa); scanf("%ld", &liPosizioa); } while(liPosizioa < 0 || liPosizioa > liAzkenPosizioa); Aldaketa(sFitxIzen, liPosizioa); printf("\n"); DatuGuztiakErakutsi(sFitxIzen); } else printf("'%s' fitxategia ez da existitzen, agur...", sFitxIzen); printf("\nPrograma bukatzera doa. Edozein tekla sakatu! "); getch(); // itxaron edozein tekla sakatu arte printf("\n"); return 0; } // Funtzio honek fitxategi baten existentzia frogatzen du. int iFitxategirikBada(const char sFitxIzen[]) { FILE *f; // Irakurketarako irekitze saiakera ("r" = read) f = fopen(sFitxIzen, "rb"); // Fitxategirik ez balego fopen() funtzioak NULL itzuliko luke if (f != NULL) { fclose(f); // fitxategia itxi baliabidwak askatzeko return 1; // Itzuli 1 (true): fitxategia bada } // Fitxategirik ez balego fopen() funtzioak NULL itzuliko luke return 0; // Itzuli 0 (false): fitxategia ez da existitzen } // fitxategiaren prozesaketa osoa void DatuGuztiakErakutsi(const char sFitxIzen[]) { FILE *f; struct tstFitxa stElem; int iPosizioa; // fitxategi bitarra irakurketa moduan ireki f = fopen(sFitxIzen, "rb"); if (f == NULL) { printf("Errorea '%s' fitxategia irekitzean 'DatuGuztiakErakutsi()' funtzioan \a\n", sFitxIzen); return; } else { // fitxategiko datuak banan-banan irakurri eta pantailan erakutsi iPosizioa = 0; while (fread(&stElem, sizeof(struct tstFitxa), 1, f)) // irakurtzerik dagoen bitartean... { printf("Ikaslea: %-20s Deialdia: %d Nota: %.2f\n", stElem.sIzenDeiturak, stElem.iDeialdia, stElem.fNota); iPosizioa++; } fclose(f); } } // fitxategiko elementuen kopurua kalkulatzeko long liZenbatElementu(const char sFitxIzen[]) { FILE *f; long liZenbatBit;; // fitxategi bitarra irakurketa moduan ireki f = fopen(sFitxIzen, "rb"); // fitxategiaren bukaeran kokatu fseek(f, 0L, SEEK_END); // fitxategiaren tamaina eskuratu liZenbatBit = ftell(f); fclose(f); return liZenbatBit/sizeof(struct tstFitxa); } // dagoena erakutsi, erregistroa balioz igarotzen da eta ez da aldatuko void DagoenaIkusi(const struct tstFitxa stElem) { printf("Ikaslea: %-20s %5d %8.2f\n", stElem.sIzenDeiturak, stElem.iDeialdia, stElem.fNota); } // datua bildu, erregistroa erreferentziaz idarotzen da aldatua izan dadin void DatuaBildu(struct tstFitxa *stElem) { printf("'%s' ikaslearen nota berria eman: ", stElem->sIzenDeiturak); scanf("%f", &stElem->fNota); } // aldaketarako ezaguna da elementuaren posizioa fitxategian void Aldaketa(const char sFitxIzen[], long liPosizioa) { FILE *f ; struct tstFitxa stElem; f = fopen(sFitxIzen, "r+b"); if (f == NULL) { printf("Errorea '%s' fitxategia irekitzean 'Aldaketa()' funtzioan \a\n", sFitxIzen); return; } fseek(f, liPosizioa*(long)sizeof(struct tstFitxa), SEEK_SET); fread(&stElem, sizeof(struct tstFitxa), 1, f); DagoenaIkusi(stElem); DatuaBildu(&stElem); fseek(f, liPosizioa*(long)sizeof(struct tstFitxa), SEEK_SET); // fseek(f, (-1)*(long)sizeof(struct tstFitxa), SEEK_CUR); // dagoen tokitik posizio bat atzera fwrite(&stElem, sizeof(struct tstFitxa), 1, f); fclose(f); }
iruzkinik ez:
Argitaratu iruzkina