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

Ariketa 89 | Elementu berri bat txertatu: 14. algoritmoa

ZER DAKIDAN:
Fitxategiak eta arrayak antzekoak dira datu-mota bereko hainbat elementu gordetzen dituztelako. Algoritmo batzuk errazagoak dira arrayetan fitxategietan baino; adibidez, elementu berri bat txertatzea errazago egiten da array batean fitxategi batean baino. Horregatik...



ZER IKASIKO DUDAN:
...horregatik, fitxategiko elementu guztiak array batera eramango ditut, arrayan elementu berria tartekatuko dut, eta, bukatzeko, arrayaren informazio berritua hasierako fitxategian gordeko dut.
Horrez gain, bigarren fitxategi laguntzaile baten partehartzearekin elementu berria txertatuko dut helburuko fitxategian.

Datuak gordetzen dituen fitxategi bat daukagu. Esate baterako, erregistroen fitxategi bat daukagu eta elementu berri bat txertatu nahi da liNon posizio ezagun batean (liNon posizioaren balioa teklatuz emango du erabiltzaileak).

Elementu berriaren txertaketa burutzeko egitura laguntzaileren bat beharko dugu. Jarraian erakusten den bi programetan egitura laguntzaileak hauek izango dira:

  • Ariketa-89_Fitxategien_14a_algoritmoa adibidean erregistroen array laguntzaile bat
  • Ariketa-89_Fitxategien_14b_algoritmoa adibidean erregistroen fitxategi laguntzaile bat

Erakusten den programa honetan array laguntzaile bat erabiliko denez, frogatu beharko da fitxategiko elementu guztiek tokia izan dezaketela arrayan. Fitxategiaren informazioa arrayan dagoelarik, txertaketa egiteko 10. jarduera | Txertaketa array batean ikusi zen algoritmoa aplikatuko da.

/* Ariketa-89_Fitxategien_14a_algoritmoa: txertatu */

// Erregistroen fitxategi batetan elementu berri bat txertatzeko
// fitxategiko edukia array batera igaroko da, txertaketa arrayan
// gauzatu eta arrayaren informazio berritua fitxategira ekarri.

#include <stdio.h>
#include <conio.h>    // getch() funtzioarako

#define BEHEMUGA 0
#define GOIMUGA 10
#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  // struct definitzen ikasleen datuak gordetzeko
{
    char sIzenDeiturak[DATU_IZEN_MAX];
    int iDeialdia;
    float fNota;
};

int iFitxategiaExistitzenDa(const char sFitxIzen[]);
void FitxategiaIkusi(const char sFitxIzen[]);
void FitxategitikBektoreaBete(const char sFitxIzen[],
                              struct tstFitxa A[],
                              long int *liLuzera);
void BektoretikFitxategiaBete(const char sFitxIzen[],
                              const struct tstFitxa A[],
                              long int liLuzera);
void BektoreaIkusi(const struct tstFitxa A[], int liLuzera);
void Tartekaketa(struct tstFitxa A[],
                 long int *liLuzera,
                 const struct tstFitxa stElementu,
                 long int liNon);
void DatuakEskuratu(struct tstFitxa *stElementua);
long int liFitxategiarenElemKopKalkulatu(const char sFitxIzen[]);


int main()
{
    char sFitxIzen[FITX_IZEN_MAX];
    char sFitxIzenLaburra[FITX_IZEN_MAX];
    struct tstFitxa stElementuBerria;
    long int liZenbatElem, liNon, liLuzera;
    struct tstFitxa A[GOIMUGA];

    printf("'C:\\Tokia\\' karpetako fitxategiaren izen laburra eman ezazu.\n");
    printf("Adibidez, 'Datuak' izena: ");
    scanf("%s", sFitxIzenLaburra);
    getchar(); // Enter karakterea kentzeko
    snprintf(sFitxIzen, sizeof(sFitxIzen), "C:\\Tokia\\%s.dat", sFitxIzenLaburra);

    if (iFitxategiaExistitzenDa(sFitxIzen) == 1)
    {
        FitxategiaIkusi(sFitxIzen);

        liZenbatElem = liFitxategiarenElemKopKalkulatu(sFitxIzen);

        if (liZenbatElem < GOIMUGA)
        {
            FitxategitikBektoreaBete(sFitxIzen, A, &liLuzera);
            BektoreaIkusi(A, liLuzera);

            printf("Elementu berriari dagozkion datuak jaso...\n");
            DatuakEskuratu(&stElementuBerria);

            do
            {
                printf("Elementu berriaren posizioa bektorean (%d - %ld): ", BEHEMUGA, liLuzera);
                scanf("%ld", &liNon);
            } while (liNon < BEHEMUGA || liNon > liLuzera);

            Tartekaketa(A, &liLuzera, stElementuBerria, liNon);
            BektoreaIkusi(A, liLuzera);
            BektoretikFitxategiaBete(sFitxIzen, A, liLuzera);
            FitxategiaIkusi(sFitxIzen);
        } else
            printf("Fitxategia handiegia da programa honentzako, bektorearen muga %d elementu delako.\n", GOIMUGA);
    }
    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;
}


// fitxategirik baden frogatzeko
int iFitxategiaExistitzenDa(const char sFitxIzen[])
{
    FILE *f;

    f = fopen(sFitxIzen, "rb");
    if (f != NULL)
    {
        fclose(f);
        return 1;
    }
    return 0;
}


// fitxategiaren edukia bistaratzeko
void FitxategiaIkusi(const char sFitxIzen[])
{
    FILE *fFitxategia;
    struct tstFitxa stElem;
    long int liPosizioa;

    fFitxategia = fopen(sFitxIzen, "rb");

    if (!fFitxategia)
    {
        printf("Ezin da fitxategia ireki\n");
        return;
    }

    printf("Fitxategiaren edukia:\n");
    liPosizioa = 0;
    while (fread(&stElem, sizeof(struct tstFitxa), 1, fFitxategia) == 1)
    {
        printf("%2ld posizioan:  | %-25s | %d | %.2f |\n", liPosizioa, stElem.sIzenDeiturak, stElem.iDeialdia, stElem.fNota);
        liPosizioa++;
    }
    printf("\n");

    fclose(fFitxategia);
}


// fitxategitik array batera datuak kargatzeko
void FitxategitikBektoreaBete(const char sFitxIzen[], struct tstFitxa A[], long int *liLuzera)
{
    FILE *fFitxategia;
    int liIndizea = BEHEMUGA;
    struct tstFitxa stElem;

    fFitxategia = fopen(sFitxIzen, "rb");
    if (!fFitxategia)
    {
        printf("Ezin da fitxategia ireki\n");
        return;
    }

    while (fread(&stElem, sizeof(struct tstFitxa), 1, fFitxategia) == 1 && liIndizea < GOIMUGA)
    {
        A[liIndizea++] = stElem;
    }
    *liLuzera = liIndizea;

    fclose(fFitxategia);
}


// array batetik fitxategian idatzi
void BektoretikFitxategiaBete(const char sFitxIzen[], const struct tstFitxa A[], long int liLuzera)
{
    FILE *fFitxategia;

    fFitxategia = fopen(sFitxIzen, "wb");
    if (!fFitxategia)
    {
        printf("Ezin da fitxategia ireki\n");
        return;
    }

    fwrite(A, sizeof(struct tstFitxa), liLuzera, fFitxategia);
    fclose(fFitxategia);
}


// arrayaren edukia bistaratzeko
void BektoreaIkusi(const struct tstFitxa A[], int liLuzera)
{
    printf("A arrayaren edukia:\n");
    for (int i = BEHEMUGA; i < liLuzera; i++)
    {
        printf("%2d posizioan     %-20s %8d %10.2f\n", i, A[i].sIzenDeiturak, A[i].iDeialdia, A[i].fNota);
    }
    printf("\n");
}


// elementu berri bat arrayan txertatzeko posizio jakin batean
void Tartekaketa(struct tstFitxa Z[], long int *liLuzera, const struct tstFitxa stElementu, long int liNon)
{
    for (int i = *liLuzera; i > liNon; i--)
    {
        Z[i] = Z[i - 1];
    }
    Z[liNon] = stElementu;
    (*liLuzera)++;
}


// elementu berri baten datuak eskuratzeko
void DatuakEskuratu(struct tstFitxa *stElementua)
{
    printf("Ikaslearen izen-deitura eman: ");
    gets(stElementua->sIzenDeiturak);

    printf("Ikaslearen deialdia eman: ");
    scanf("%u", &stElementua->iDeialdia);

    printf("Ikaslearen nota eman: ");
    scanf("%f", &stElementua->fNota);

    getchar(); // Enter karakterea kentzeko
}


// fitxategiko elementu kopurua itzultzeko
long int liFitxategiarenElemKopKalkulatu(const char sFitxIzen[])
{
    FILE *fFitxategia;
    long int liElemKopurua = 0;

    fFitxategia = fopen(sFitxIzen, "rb");

    if (!fFitxategia)
    {
        printf("Ezin da fitxategia ireki\n");
        return -1;
    }

    fseek(fFitxategia, 0L, SEEK_END);
    liElemKopurua = ftell(fFitxategia) / sizeof(struct tstFitxa);
    fclose(fFitxategia);

    return liElemKopurua;
}


Erakusten den programa honetan bigarren fitxategi laguntzaile bat erabiliko da. Emaitza den informazioa fitxategi laguntzailean biltegituko denez, hasierako fitxategia ezabatuko da remove() eginez eta fitxategi laguntzaileari izena aldatuko zaio rename() eginez.

/* Ariketa-89_Fitxategien_14b_algoritmoa: txertatu */

// Erregistroen fitxategi batetan elementu berri bat txertatzeko
// beste fitxategi laguntzaile bat erabiliko da. Azkenean, lana
// burutu ondoren, jatorrizko fitxategia ezabatuko da eta emaitza
// gordetzen duen fitxategi laguntzailea berrizendatuko da.

#include <stdio.h>
#include <string.h>   // strcpy() eta strcat() funtzioetarako
#include <conio.h>    // getch() funtzioarako

#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  // struct definitzen ikasleen datuak gordetzeko
{
    char sIzenDeiturak[DATU_IZEN_MAX];
    int iDeialdia;
    float fNota;
};

int iFitxategiaExistitzenDa(const char sFitxIzen[]);
void FitxategiaIkusi(const char sFitxIzen[]);
long int liFitxategiarenElemKopKalkulatu(const char sFitxIzen[]);
void DatuakEskuratu(struct tstFitxa *stElementua);
void ElementuaGehitu(const char sFitxIzen[], struct tstFitxa stElementuBerria);
void ElementuaTxertatu(const char sFitxIzen[],
                       const char sFitxIzenLaburra[],
                       struct tstFitxa stElementuBerria,
                       long liNon,
                       long liZenbatElem);

int main()
{
    char sFitxIzen[DATU_IZEN_MAX];
    char sFitxIzenLaburra[DATU_IZEN_MAX];
    struct tstFitxa stElementuBerria;
    long int liZenbatElem, liNon;


    printf("''C:\\Tokia\\'' karpetako fitxategiaren izen laburra eman ezazu.\n");
    printf("Adibidez, 'Datuak' izena: ");
    scanf("%s", sFitxIzenLaburra);
    getchar(); // Enter karakterea kentzeko
    strcpy(sFitxIzen, "C:\\Tokia\\");
    strcat(sFitxIzen, sFitxIzenLaburra);
    strcat(sFitxIzen, ".dat");

    if (iFitxategiaExistitzenDa(sFitxIzen) == 1)
    {
        FitxategiaIkusi(sFitxIzen);
        printf("Elementu berriari dagozkion datuak jaso...\n");
        DatuakEskuratu(&stElementuBerria);
        liZenbatElem = liFitxategiarenElemKopKalkulatu(sFitxIzen);
        do
        {
            printf("Elementu berriaren posizioa fitxategian (0 - %ld): ", liZenbatElem);
            scanf("%ld", &liNon);
        } while (liNon < 0 || liNon > liZenbatElem);

        if (liNon == liZenbatElem)
            ElementuaGehitu(sFitxIzen, stElementuBerria);
        else
            ElementuaTxertatu(sFitxIzen, sFitxIzenLaburra, stElementuBerria, liNon, liZenbatElem);

        FitxategiaIkusi(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;
}


// fitxategirik baden frogatzeko
int iFitxategiaExistitzenDa(const char sFitxIzen[])
{
    FILE *f;

    f = fopen(sFitxIzen, "rb");
    if (f != NULL)
    {
        fclose(f);
        return 1;
    }
    return 0;
}


// fitxategiaren edukia bistaratzeko
void FitxategiaIkusi(const char sFitxIzen[])
{
    FILE *fFitxategia;
    struct tstFitxa stElem;
    long int liPosizioa;

    fFitxategia = fopen(sFitxIzen, "rb");

    if (!fFitxategia)
    {
        printf("Ezin da fitxategia ireki\n");
        return;
    }

    printf("'%s' fitxategiaren edukia:\n", sFitxIzen);
    liPosizioa = 0;
    while (fread(&stElem, sizeof(struct tstFitxa), 1, fFitxategia) == 1)
    {
        printf("%2ld posizioan:  | %-25s | %d | %.2f |\n", liPosizioa, stElem.sIzenDeiturak, stElem.iDeialdia, stElem.fNota);
        liPosizioa++;
    }
    printf("\n");

    fclose(fFitxategia);
}


// fitxategiaren bukaeran datu berri bat gehitzeko funtzioa
void ElementuaGehitu(const char sFitxIzen[], struct tstFitxa stElementuBerria)
{
    FILE *f;
    fpos_t Posizioa;

    f = fopen(sFitxIzen, "a+b"); // fitxategia irakurtzeko eta bukaeran idazteko moduan ireki
    if (f == NULL)
    {
        printf("Errorea fitxategia irekitzean\n\a");
        return;
    }

    fgetpos(f, &Posizioa);
    fwrite(&stElementuBerria, sizeof(struct tstFitxa), 1, f); // fitxategian idatzi

    fclose(f); // fitxategia itxi
}


void ElementuaTxertatu(const char sFitxIzen[],
                       const char sFitxIzenLaburra[],
                       struct tstFitxa stElementuBerria,
                       long liNon,
                       long liZenbatElem)
{
    FILE *f, *fLAG;
    struct tstFitxa stElem;
    char sFitxIzenLAG[FITX_IZEN_MAX];
    long liKont;

    strcpy(sFitxIzenLAG, "C:\\Tokia\\");
    strcat(sFitxIzenLAG, sFitxIzenLaburra);
    strcat(sFitxIzenLAG, "LAG.dat");

    f = fopen(sFitxIzen, "rb");       // fitxategia irakurtzeko moduan ireki
    fLAG = fopen(sFitxIzenLAG, "wb"); // fitxategia idazteko moduan ireki

    for (liKont = 0; liKont < liNon; liKont++)
    {
        fread(&stElem, sizeof(struct tstFitxa), 1, f);            // aurrekoak fitxategitik irakurri
        fwrite(&stElem, sizeof(struct tstFitxa), 1, fLAG);        // aurrekoak laguntzailean idatzi
    }
    fwrite(&stElementuBerria, sizeof(struct tstFitxa), 1, fLAG);  // berria laguntzailean idatzi
    for (liKont = liNon; liKont < liZenbatElem; liKont++)
    {
        fread(&stElem, sizeof(struct tstFitxa), 1, f);            // ostekoak fitxategitik irakurri
        fwrite(&stElem, sizeof(struct tstFitxa), 1, fLAG);        // ostekoak laguntzailean idatzi
    }

    fclose(f);    // fitxategia itxi
    fclose(fLAG); // laguntzailea itxi

    remove(sFitxIzen);                // jatorrizko fitxategia ezabatu
    rename(sFitxIzenLAG, sFitxIzen);  // laguntzaileari jatorrizko izena ezarri
}


// elementu berri baten datuak eskuratzeko
void DatuakEskuratu(struct tstFitxa *stElementua)
{
    printf("Ikaslearen izen-deitura eman: ");
    gets(stElementua->sIzenDeiturak);

    printf("Ikaslearen deialdia eman: ");
    scanf("%d", &stElementua->iDeialdia);

    printf("Ikaslearen nota eman: ");
    scanf("%f", &stElementua->fNota);

    getchar(); // Enter karakterea kentzeko
}


// fitxategiko elementu kopurua itzultzeko
long int liFitxategiarenElemKopKalkulatu(const char sFitxIzen[])
{
    FILE *fFitxategia;
    long int liElemKopurua = 0;

    fFitxategia = fopen(sFitxIzen, "rb");

    if (!fFitxategia)
    {
        printf("Ezin da fitxategia ireki\n");
        return -1;
    }

    fseek(fFitxategia, 0L, SEEK_END);
    liElemKopurua = ftell(fFitxategia) / sizeof(struct tstFitxa);
    fclose(fFitxategia);

    return liElemKopurua;
}






  • Ariketa-89_Fitxategien_14a_algoritmoa.cbp | main.c  
  • Ariketa-89_Fitxategien_14b_algoritmoa.cbp | main.c  


 

iruzkinik ez:

Argitaratu iruzkina