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

Ariketa 88 | Fitxategia moztu: 13. algoritmoa

ZER DAKIDAN:
Fitxategiak zer diren badakit, eta fitxategi batek egitura lineala duela badakit.



ZER IKASIKO DUDAN:
Posizio jakin batetik aurrera, fitxategi bat mozten duen programa idatziko dut (fitxategiko informazio zati bat galduko da, noski).

Datuak gordetzen dituen fitxategi bat daukagu. Esate baterako, zenbaki osoak gordetzen duen  fitxategi bat daukagu eta bere edukiaren zati batekin geratzea nahi dugu, gainerako zatia galduz. Jarraian erakusten diren bi programetan fitxategia moztuko da puntu jakin batetik eta, ondorioz, fitxategiaren aurreneko elementuak mantenduko dira bere eduki bezala (gainerako elementuak, noski, galduko dira).

Datuen fitxategia moztu ahal izateko egitura laguntzaileren baten beharra daukagu, array bat edo bigarren fitxategi bat:

  • Ariketa-88_Fitxategien_13a_algoritmoa adibidean array laguntzaile bat erabiliko da
  • Ariketa-88_Fitxategien_13b_algoritmoa adibidean beste fitxategi laguntzaile bat erabiliko da

Erakusten den programa honetan C:\Tokia\Zenbakiak.dat izeneko fitxategiarekin lan egingo da eta moztu ondoren hasierako elementuak mantenduko ditu.

//* Ariketa-88_Fitxategien_13a_algoritmoa: posizio batetik moztu */

// 0 eta 99 arteko kopuru osoak gordetzen dituen C:\Tokia\Zenbakiak.dat
// fitxategiarekin lan egingo da, helburua fitxategi moztea da.
// Laneko C:\Tokia\Zenbakiak.dat izeneko fitxategirik ez badago sortu
// egingo da; erabiltzaileak zenbat elementu izango diren erabakiko du
// baina elementuen balioak auzaz aukeratuko ditu programak.
// Laneko C:\Tokia\Zenbakiak.dat izeneko fitxategia existitzen bada,
// erabiltzaileak erabakiko du zein posiziotik moztuko den.

// Fitxategia mozteko array laguntzaile bat erabiliko da.

#include <stdio.h>
#include <stdlib.h>  // system(), srand() eta rand() funtzioetarako
#include <time.h>    // time() funtzioarako
#include <conio.h>   // getch() funtziorako

#define FITX_IZEN_MAX 120  // fitxategiaren izenerako 119 karaktere gehi null mugatzailea
#define KOPURU_MAX 50      // gehienez 50 zenbaki fitxategi barruan

int iFitxategiaExistitzenDa(const char sFitxIzen[]);
void FitxategiZatiBatArrayra(const char sFitxIzen[], int aiLaguntzailea[], int *iLuzera);
void FitxategiaEzabatu(const char sFitxIzen[]);
void ArraytikFitxategira(const int aiLaguntzailea[], int iLuzera, const char sFitxIzen[]);
void FitxategiarenEdukiaIkusi(const char sFitxIzen[]);
void FitxategiaSortuEtaBete(const char sFitxIzen[]);


int main()
{
    char sFitxIzen[FITX_IZEN_MAX] = "C:\\Tokia\\Zenbakiak.dat";
    int aiLaguntzailea[KOPURU_MAX];
    int iLuzera;

    system("cls");
    printf("'%s' fitxategiarekin lan egingo dugu.\n", sFitxIzen);
    printf("'%s' fitxategia existitzen da? ERANTZUNA ---> %s\n", sFitxIzen, iFitxategiaExistitzenDa(sFitxIzen) ? "BAI" : "EZ");
    printf("\n");

    if (iFitxategiaExistitzenDa(sFitxIzen) == 1)
    {
        printf("Fitxategiaren elementu guztiak pantailaratuko ditugu. Hona hemen...\n");
        FitxategiarenEdukiaIkusi(sFitxIzen);

        printf("Fitxategiaren posizio batetik aurrera ebaki...\n");
        FitxategiZatiBatArrayra(sFitxIzen, aiLaguntzailea, &iLuzera);
        FitxategiaEzabatu(sFitxIzen);
        ArraytikFitxategira(aiLaguntzailea, iLuzera, sFitxIzen);

        printf("\nFitxategiaren elementu guztiak berriro pantailaratu...\n");
        FitxategiarenEdukiaIkusi(sFitxIzen);
    }
    else
    {
        printf("'%s' fitxategia ez da existitzen, orain sortuko da\n\n", sFitxIzen);
        FitxategiaSortuEtaBete(sFitxIzen);
        printf("Fitxategiaren elementu guztiak pantailaratuko ditugu. Hona hemen...\n");
        FitxategiarenEdukiaIkusi(sFitxIzen);
    }

    printf("\nEdozein tekla sakatu programa bukatzeko\n");
    getch();
    return 0;
}


void FitxategiarenEdukiaIkusi(const char sFitxIzen[])
{
    FILE *fErak = fopen(sFitxIzen, "rb");
    if (fErak == NULL)
    {
        printf("Errorea '%s' fitxategia irekitzerakoan FitxategiarenEdukiaIkusi() funtzioan\n", sFitxIzen);
        return;
    }

    int iElem, pos = 0;
    printf("Fitxategiaren edukia:\n");
    while (fread(&iElem, sizeof(int), 1, fErak) == 1)
    {
        printf("%8d. elementua = %d\n", pos, iElem);
        pos++;
    }

    printf("\n");
    fclose(fErak);
}


void FitxategiZatiBatArrayra(const char sFitxIzen[], int aiLaguntzailea[], int *iLuzera)
{
    FILE *fErak;
    int iZenbatElementu;
    int iPosizioa;
    int iElem;

    fErak = fopen(sFitxIzen, "r+b");
    if (fErak == NULL)
    {
        printf("Errorea '%s 'fitxategia irekitzerakoan FitxategiZatiBatArrayra() funtzioan:\n", sFitxIzen);
        return;
    }

    fseek(fErak, 0L, SEEK_END);
    iZenbatElementu = ftell(fErak) / sizeof(int);

    if (iZenbatElementu == 0 || iZenbatElementu == 1)
    {
         if (iZenbatElementu == 0)
            printf("Fitxategia existitzen da baina hutsik dago, ezin da moztu!\n");
         if (iZenbatElementu == 1)
            printf("Fitxategiak elementu bakar bat dauka eta ez da onartzen moztea!\n");
    }
    else
    {
        do
        {
            printf("%s fitxategiaren datuen esparrua: 0..%d\n", sFitxIzen, iZenbatElementu - 1);
            printf("Zein elementutik moztu nahi duzu? ");
            scanf("%d", &iPosizioa);
            if (iPosizioa == 0)
                printf("Ez da onartzen, gutxienez elementu bat nahi delako fitxategian\n");
            if  (iPosizioa < 0 || iPosizioa >= iZenbatElementu)
                printf("Ez da onartzen, fitxategiko esparruaren barruko datua behar delako\n");
        } while (iPosizioa < 1 || iPosizioa >= iZenbatElementu);


        fseek(fErak, 0L, SEEK_SET);   // fitxategiaren hasieran kokatu
        *iLuzera = 0;
        for (int iKont = 0; iKont < iPosizioa; iKont++)
        {
            fread(&iElem, sizeof(int), 1, fErak);
            (*iLuzera)++;
            aiLaguntzailea[iKont] = iElem;
        }
    }

    fclose(fErak);
}


void FitxategiaEzabatu(const char sFitxIzen[])
{
    if (remove(sFitxIzen) == 0)
        printf("\n'%s' fitxategia  ezabatu da.\n", sFitxIzen);
    else
        printf("\nErrorea '%s' ezabatzerakoan.\n", sFitxIzen);
}


// arrayaren edukia fitxategi batean gordetzeko funtzioa
void ArraytikFitxategira(const int aiLaguntzailea[], int iLuzera, const char sFitxIzen[])
{
    FILE *f;

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

    for (int i = 0; i < iLuzera; i++)
    {
        fwrite(&aiLaguntzailea[i], sizeof(int), 1, f);
    }
    fclose(f);
}


int iFitxategiaExistitzenDa(const char sFitxIzen[])
{
    FILE *f;

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


void FitxategiaSortuEtaBete(const char sFitxIzen[])
{
    FILE *f;
    int iElem;
    int iZenbatElementu;

    f = fopen(sFitxIzen, "wb");
    if (f == NULL)
    {
        printf("Errorea '%s 'fitxategia irekitzerakoan FitxategiaSortuEtaBete() funtzioan:\n", sFitxIzen);
        return;
    }
    do
    {
        printf("Zenbat elementu nahi dituzu %s fitxategian? ", sFitxIzen);
        scanf("%d", &iZenbatElementu);
        getchar(); // bufferra garbitu
        if (iZenbatElementu <= 1)
            printf("Gutxienez 2 elementu behar dira\n");
        if (iZenbatElementu > KOPURU_MAX)
            printf("Gehienez %d elementu izango dira\n", KOPURU_MAX);
    } while (iZenbatElementu <= 1 || iZenbatElementu > KOPURU_MAX);

    srand(time(NULL));
    for (int iKont = 0; iKont < iZenbatElementu; iKont++)
    {
        iElem = rand()%100;
        fwrite(&iElem, sizeof(int), 1, f);
    }
    fclose(f);
}


Erakusten den programa honetan C:\Tokia\Zenbakiak.dat izeneko fitxategiarekin lan egingo da eta moztu ondoren hasierako elementuak mantenduko ditu.

/* Ariketa-88_Fitxategien_13b_algoritmoa: posizio batetik moztu */

// 0 eta 99 arteko kopuru osoak gordetzen dituen C:\Tokia\Zenbakiak.dat
// fitxategiarekin lan egingo da, helburua fitxategi moztea da.
// Laneko C:\Tokia\Zenbakiak.dat izeneko fitxategirik ez badago sortu
// egingo da; erabiltzaileak zenbat elementu izango diren erabakiko du
// baina elementuen balioak auzaz aukeratuko ditu programak.
// Laneko C:\Tokia\Zenbakiak.dat izeneko fitxategia existitzen bada,
// erabiltzaileak erabakiko du zein posiziotik moztuko den.

// Fitxategia mozteko fitxategi laguntzaile bat erabiliko da.

#include <stdio.h>
#include <stdlib.h>  // system(), srand() eta rand() funtzioetarako
#include <time.h>    // time() funtzioarako
#include <conio.h>   // getch() funtziorako

#define FITX_IZEN_MAX 120  // fitxategiaren izenerako 119 karaktere gehi null mugatzailea

int iFitxategiaExistitzenDa(const char sFitxIzen[]);
void FitxategiZatiBatLaguntzailera(const char sFitxIzen[], const char sFitx_Lag[]);
void FitxategiaEzabatu(const char sFitxIzen[]);
void FitxategiaBerrizendatu(const char sFitxIzenZaharra[], const char sFitxIzenBerria[]);
void FitxategiarenEdukiaIkusi(const char sFitxIzen[]);
void FitxategiaSortuEtaBete(const char sFitxIzen[]);


int main()
{
    char sFitxIzen[FITX_IZEN_MAX] = "C:\\Tokia\\Zenbakiak.dat";
    char sFitx_Lag[FITX_IZEN_MAX] = "C:\\Tokia\\Laguntzailea.dat";

    system("cls");
    printf("'%s' fitxategiarekin lan egingo dugu.\n", sFitxIzen);
    printf("'%s' fitxategia existitzen da? ERANTZUNA ---> %s\n", sFitxIzen, iFitxategiaExistitzenDa(sFitxIzen) ? "BAI" : "EZ");
    printf("\n");

    if (iFitxategiaExistitzenDa(sFitxIzen) == 1)
    {
        printf("Fitxategiaren elementu guztiak pantailaratuko ditugu. Hona hemen...\n");
        FitxategiarenEdukiaIkusi(sFitxIzen);

        printf("Fitxategiaren posizio batetik aurrera ebaki...\n");
        FitxategiZatiBatLaguntzailera(sFitxIzen, sFitx_Lag);
        FitxategiaEzabatu(sFitxIzen);
        FitxategiaBerrizendatu(sFitx_Lag, sFitxIzen);

        printf("\nFitxategiaren elementu guztiak berriro pantailaratu...\n");
        FitxategiarenEdukiaIkusi(sFitxIzen);
    }
    else
    {
        printf("'%s' fitxategia ez da existitzen, orain sortuko da\n\n", sFitxIzen);
        FitxategiaSortuEtaBete(sFitxIzen);
        printf("Fitxategiaren elementu guztiak pantailaratuko ditugu. Hona hemen...\n");
        FitxategiarenEdukiaIkusi(sFitxIzen);
    }

    printf("\nEdozein tekla sakatu programa bukatzeko\n");
    getch();
    return 0;
}


void FitxategiarenEdukiaIkusi(const char sFitxIzen[])
{
    FILE *fErak = fopen(sFitxIzen, "rb");
    if (fErak == NULL)
    {
        printf("Errorea '%s' fitxategia irekitzerakoan FitxategiarenEdukiaIkusi() funtzioan\n", sFitxIzen);
        return;
    }

    int iElem, pos = 0;
    printf("Fitxategiaren edukia:\n");
    while (fread(&iElem, sizeof(int), 1, fErak) == 1)
    {
        printf("%8d. elementua = %d\n", pos, iElem);
        pos++;
    }

    printf("\n");
    fclose(fErak);
}


void FitxategiZatiBatLaguntzailera(const char sFitxIzen[], const char sFitx_Lag[])
{
    FILE *fErak;
    FILE *f_Lag;
    int iZenbatElementu;
    int iPosizioa;
    int iElem;

    fErak = fopen(sFitxIzen, "r+b");
    if (fErak == NULL)
    {
        printf("Errorea '%s 'fitxategia irekitzerakoan FitxategiZatiBatLaguntzailera() funtzioan:\n", sFitxIzen);
        return;
    }
    f_Lag = fopen(sFitx_Lag, "wb");   // berria sortuko duenez ez da erroreik gertatuko

    fseek(fErak, 0L, SEEK_END);
    iZenbatElementu = ftell(fErak) / sizeof(int);

    if (iZenbatElementu == 0 || iZenbatElementu == 1)
    {
         if (iZenbatElementu == 0)
            printf("Fitxategia existitzen da baina hutsik dago, ezin da moztu!\n");
         if (iZenbatElementu == 1)
            printf("Fitxategiak elementu bakar bat dauka eta ez da onartzen moztea!\n");
    }
    else
    {
        do
        {
            printf("%s fitxategiaren datuen esparrua: 0..%d\n", sFitxIzen, iZenbatElementu - 1);
            printf("Zein elementutik moztu nahi duzu? ");
            scanf("%d", &iPosizioa);
            if (iPosizioa == 0)
                printf("Ez da onartzen, gutxienez elementu bat nahi delako fitxategian\n");
            if  (iPosizioa < 0 || iPosizioa >= iZenbatElementu)
                printf("Ez da onartzen, fitxategiko esparruaren barruko datua behar delako\n");
        } while (iPosizioa < 1 || iPosizioa >= iZenbatElementu);


        fseek(fErak, 0L, SEEK_SET);   // fitxategiaren hasieran kokatu
        for (int iKont = 0; iKont < iPosizioa; iKont++)
        {
            fread(&iElem, sizeof(int), 1, fErak);
            fwrite(&iElem, sizeof(int), 1, f_Lag);
        }
    }

    fclose(fErak);
    fclose(f_Lag);
}


void FitxategiaEzabatu(const char sFitxIzen[])
{
    if (remove(sFitxIzen) == 0)
        printf("\n'%s' fitxategia  ezabatu da.\n", sFitxIzen);
    else
        printf("\nErrorea '%s' ezabatzerakoan.\n", sFitxIzen);
}


void FitxategiaBerrizendatu(const char sFitxIzenZaharra[], const char sFitxIzenBerria[])
{
    if (rename(sFitxIzenZaharra, sFitxIzenBerria) == 0)
        printf("\n'%s' fitxategiaren izen zaharra\n'%s' izen berrira aldatu da.\n", sFitxIzenZaharra, sFitxIzenBerria);
    else
        printf("Errorea izena aldatzean.\n");
}


int iFitxategiaExistitzenDa(const char sFitxIzen[])
{
    FILE *f;

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


void FitxategiaSortuEtaBete(const char sFitxIzen[])
{
    FILE *f;
    int iElem;
    int iZenbatElementu;

    f = fopen(sFitxIzen, "wb");
    if (f == NULL)
    {
        printf("Errorea '%s 'fitxategia irekitzerakoan FitxategiaSortuEtaBete() funtzioan:\n", sFitxIzen);
        return;
    }
    do
    {
        printf("Zenbat elementu nahi dituzu %s fitxategian? ", sFitxIzen);
        scanf("%d", &iZenbatElementu);
        getchar(); // bufferra garbitu
        if (iZenbatElementu <= 1)
            printf("Gutxienez 2 elementu behar dira\n");
    } while (iZenbatElementu <= 1);

    srand(time(NULL));
    for (int iKont = 0; iKont < iZenbatElementu; iKont++)
    {
        iElem = rand()%100;
        fwrite(&iElem, sizeof(int), 1, f);
    }
    fclose(f);
}






  • Ariketa-88_Fitxategien_13a_algoritmoa.cbp | main.c  
  • Ariketa-88_Fitxategien_13b_algoritmoa.cbp | main.c  


 

iruzkinik ez:

Argitaratu iruzkina