2025(e)ko apirilaren 9(a), asteazkena

Ariketa 78 | Fitxategiaren existentzia: 3. algoritmoa

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, fitxategi baten existentzia ezagutzeko access() funtzioa ikusiko dut fitxategia irekitzean behar den w, r eta a marka ongi aukeratzeko. Baina, fitxategi baten existentzia ezagutzeko fopen() funtzioa erabiltzen ikasiko dut.

Fitxategi bat irekitzerakoan w, r eta a moduetatik zein aplikatu ahal dugun jakiteko, ezagutu behar dugu fitxategia existitzen den ala ez. Fitxategi baten existentzia frogatzeko access() aipatuko dugu, baina fopen() funtzioaren bitartez egiten ikasiko dugu.

Azpimarra dezagun access() funtzioak ez duela FILE datu-motako parametrorik eta ondorioz programa nagusian erabil daitekeela. Hau da access() funtzioaren prototipoa:

              #include <unistd.h>
              int access(const char *pathname, int how);

Non pathname lehen parametroa irisgarritasuna probatu nahi zaion fitxategiaren izena den (kate bat eta kate bati seinalatzen dion erakuslea), eta, how bigarren parametroak adierazten duen zein diren probatu nahi ditugun sarbide-moduak eta unistd.h liburutegian honako sinboloak definitu dira how parametroan erabiltzeko:

  • F_OK egiazta ezazu fitxategia existitzen den
  • R_OK egiazta ezazu ea fitxategitik irakur daitekeen
  • W_OK egiazta ezazu fitxategia eskuragarri dagoen idazteko
  • X_OK egiazta ezazu fitxategia existitzen den

Azken hiru sinboloetako edozein edo guztiak har daitezke zenbait sarbide-modu aldi berean probatzeko. Baina F_OK erabiltzean, fitxategia existitzen den egiaztatzeko, ezin daiteke beste sinbolorik erabili.

Zer balio itzultzen du access() funtzioak?

  • Zehaztutako sarbidea onartzen bada, access() funtzioak 0 itzuliko du
  • Adierazitako fitxategira ezin bada zehaztutako moduan sartu, access() funtzioak -1 itzuliko du eta errno aldagai orokorrean erroreari dagokion balioa ezarriko du

access() funtzioa oso gomendagarria izan arren, fopen() funtzioa erabil daiteke ere fitxategi baten existencia ziurtatzeko.


Erakusten den programa honetan fitxategiaren existentzia frogatzen da programa nagusian iFitxategirikBada() funtzioari deia eginez, horren arabera:

  • Baldin eta fitxategia bada, ondoko hiru lanak burutuko dira:
    1. Zehaztutako fitxategiaren edukia pantailaratu
    2. Fitxategiari elementu berriak gehitu
    3. Fitxategiaren eduki berria pantailaratu
  • Baldin eta fitxategirik ez bada, ondoko bi lanak burutuko dira:
    1. Fitxategia berriki sortu eta elementuz hornitu
    2. Fitxategiaren edukia pantailaratu

Programa bukatu aurretik, fitxategiari izena aldatuko zaio bere edukia mantenduz.

/* Ariketa-78_Fitxategien_3_algoritmoa: Funtzio berezia erabili ahal da fitxategia
                                        irakurketarako ala idazketarako zabaltzeko */

// iFitxategirikBada() funtzioa programa nagusian erabil daiteke eta hartzen duen
//                     parametro bakarra fitxategiaren izena da.
//                     Fitxategiaren irekitze saiakera burutzen da eta arazoren bat
//                     gertatuz gero, suposatuko da fitxategia ez dela existitzen.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>   // strcpy() funtziorako
#include <ctype.h>    // toupper() funtziorako
#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
{
    char sIzenDeiturak[DATU_IZEN_MAX];
    int iDeialdia;
    float fNota;
};


int iFitxategirikBada(const char sFitxIzen[]);
void DatuakErakutsi(const struct tstFitxa *stFitxa);
void DatuakJaso(struct tstFitxa *stFitxa);
void FitxategiaSortuEtaBete(const char sFitxIzen[]);
void FitxategiaIkusi(const char sFitxIzen[]);
void FitxategiariElementuakGehitu(const char sFitxIzen[]);
void FitxategiaBerrizendatu(const char sFitxIzen[], char sFitxIzenBerria[]);


int main()
{
    char sFitxIzen[FITX_IZEN_MAX];
    char sFitxIzenBerria[FITX_IZEN_MAX];
    char sFitxIzenPath[FITX_IZEN_MAX];

    printf("Fitxategia existitzen da eta datuak ditu\n(adibidez C:\\Tokia\\Ikasleak.DAT)\n\n");
    printf("Fitxategiaren izena eman (adibidez 'Ikasleak.DAT'): ");
    gets(sFitxIzen);

    strcpy(sFitxIzenPath, sBIDEA);
    strcat(sFitxIzenPath, sFitxIzen);
    printf("Fitxategiaren izen osoa: >>>%s<<<\n\n", sFitxIzenPath);

    if (iFitxategirikBada(sFitxIzenPath) == 1)
    {
        printf("'%s' fitxategia existitzen da, lan egin dezagun.\n", sFitxIzenPath);
        FitxategiaIkusi(sFitxIzenPath);
        printf("'%s' fitxategian elementu berria gehituko dugu...\n", sFitxIzenPath);
        FitxategiariElementuakGehitu(sFitxIzenPath);
        FitxategiaIkusi(sFitxIzenPath);
    }
    else
    {
        printf("'%s' fitxategia ez da existitzen, sortuko dugu.\n", sFitxIzenPath);
        FitxategiaSortuEtaBete(sFitxIzenPath);
        FitxategiaIkusi(sFitxIzenPath);
    }

    FitxategiaBerrizendatu(sFitxIzenPath, sFitxIzenBerria);
    printf("Izena bai, baina '%s' fitxategiaren\nedukia ez da aldatu.\n", sFitxIzenBerria);
    FitxategiaIkusi(sFitxIzenBerria);

    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
}


// Funtzio honek estruktura baten datuak pantailaratzen ditu.
// Parametro bakarra da eta sarrerakoa da, beraz balioz pasatzen da.
void DatuakErakutsi(const struct tstFitxa *stFitxa)
{
    printf("Ikaslea: %-20s  Deialdia: %d  Nota: %.2f\n",
           stFitxa->sIzenDeiturak, stFitxa->iDeialdia, stFitxa->fNota);
}


// Funtzio honek estruktura baten datuak jasotzen ditu. Parametro
// bakarra da eta irteerakoa da, beraz erreferentziaz pasatzen da.
void DatuakJaso(struct tstFitxa *stFitxa)
{
    printf("Ikaslearen izena: ");
    gets(stFitxa->sIzenDeiturak);

    printf("Deialdia: ");
    scanf("%u", &stFitxa->iDeialdia);

    printf("Nota: ");
    scanf("%f", &stFitxa->fNota);
    getchar(); // lerro-berri karakterea kontsumitu
}


// Funtzio honek fitxategiaren izena hartzen du, sarrerako datua da fitxategiaren
// izena aldatzen ez delako. Funtzioan definituko da FILE datu-motatako aldagaia,
// eta funtzioaren hasieran 'fopen' egingo da (r marka irakurtzeko eta b marka
// fitxategi bitarra delako); errorea gertatzen bada irten, bestela datuekin lan
// egin fread() eta fwrite() desberdinak aplikatuz; eta azkenean, funtziotik irten
// baino lehen, fitxategia itxi beharko da 'fclose' bat eginez.
void FitxategiaIkusi(const char sFitxIzen[])
{
    FILE *f;
    struct tstFitxa stFitxa;
    int pos = 0;

    f = fopen(sFitxIzen, "rb");
    if (f == NULL)
    {
        printf("Errorea '%s' fitxategia irekitzean 'FitxategiaIkusi()' funtzioan \a\n", sFitxIzen);
        exit(1);
    }

    printf("%s fitxategiak edukia du:\n", sFitxIzen);
    while (fread(&stFitxa, sizeof(struct tstFitxa), 1, f) == 1)
    {
        printf("%d. ", pos);
        DatuakErakutsi(&stFitxa);
        pos++;
    }
    fclose(f);
}


// Funtzio honek fitxategiaren izena hartzen du, sarrerako datua da fitxategiaren
// izena aldatzen ez delako. Funtzioan definituko da FILE datu-motatako aldagaia,
// eta funtzioaren hasieran 'fopen' egingo da (w marka berria delako eta b marka
// fitxategi bitarra delako); errorea gertatzen bada irten, bestela datuekin lan
// egin fread() eta fwrite() desberdinak aplikatuz; eta azkenean, funtziotik irten
// baino lehen, fitxategia itxi beharko da 'fclose' bat eginez.
void FitxategiaSortuEtaBete(const char sFitxIzen[])
{
    FILE *f;
    struct tstFitxa stFitxa;
    int iKopurua;
    int iKont;

    f = fopen(sFitxIzen, "wb");
    if (f == NULL)
    {
        printf("Errorea '%s' fitxategia irekitzean 'FitxategiaSortuEtaBete()' funtzioan \a\n", sFitxIzen);
        exit(1);
    }

    printf("Zenbat elementu nahi dituzu %s fitxategian? ", sFitxIzen);
    scanf("%d", &iKopurua);
    getchar(); // lerro-berri karakterea kontsumitu

    for (iKont = 0; iKont < iKopurua; iKont++)
    {
        printf("%d posizioko ikaslearen datuak biltzen...\n", iKont);
        DatuakJaso(&stFitxa);
        fwrite(&stFitxa, sizeof(struct tstFitxa), 1, f);
    }

    fclose(f);
}


// Funtzio honek fitxategiaren izena hartzen du, sarrerako datua da fitxategiaren
// izena aldatzen ez delako. Funtzioan definituko da FILE datu-motatako aldagaia,
// eta funtzioaren hasieran 'fopen' egingo da (a marka aldatuko delako eta b marka
// fitxategi bitarra delako); errorea gertatzen bada irten, bestela datuekin lan
// egin fread() eta fwrite() desberdinak aplikatuz; eta azkenean, funtziotik irten
// baino lehen, fitxategia itxi beharko da 'fclose' bat eginez.                                               }
void FitxategiariElementuakGehitu(const char sFitxIzen[])
{
    FILE *f;
    struct tstFitxa stFitxa;
    char cErantz;

    f = fopen(sFitxIzen, "ab");
 // f = fopen(sFitxIzen, "r+b");  edo hau ere, baina gero bukaeran kokatuz...   
    if (f == NULL)
    {
        printf("Errorea '%s' fitxategia irekitzean 'FitxategiariElementuakGehitu()' funtzioan \a\n", sFitxIzen);
        exit(1);
    }

    do
    {
        DatuakJaso(&stFitxa);
     // fseek(f, 0L, SEEK_END);  baldin eta irekiera "r+b" moduan egin bada
        fwrite(&stFitxa, sizeof(struct tstFitxa), 1, f);

        printf("Datu gehiagorik gorde nahi duzu? (B/E) ");
        cErantz = getch();
        cErantz = toupper(cErantz);
        printf("%c\n", cErantz);
    } while (cErantz != 'E');

    fclose(f);
}


void FitxategiaBerrizendatu(const char sFitxIzen[], char sFitxIzenBerria[])
{
    char sFitxIzenBerriaPath[FITX_IZEN_MAX];

    printf("Fitxategi berriaren izena eman ezazu: ");
    gets(sFitxIzenBerria);

    strcpy(sFitxIzenBerriaPath, sBIDEA);
    strcat(sFitxIzenBerriaPath, sFitxIzenBerria);

    if (rename(sFitxIzen, sFitxIzenBerriaPath) != 0)
        printf("Errorea fitxategiari izena aldatzean\n");
    else
        strcpy(sFitxIzenBerria, sFitxIzenBerriaPath);
}






  • Ariketa-78_Fitxategien_3_algoritmoa.cbp | main.c  


 

iruzkinik ez:

Argitaratu iruzkina