2025(e)ko apirilaren 21(a), astelehena

Azken ariketa | main() funtzioaren parametroak







Gure programak exekutatzeko komandoen terminala erabil daiteke. Komando terminal bat baino gehiago izan dezakegu instalaturik gure konputagailuan, adibidez: cmd eta PowerShell. Bietariko edozein irekitzeko joan sistemaren bilatzailera eta bertan idatzi terminalaren izena.

cmd komando terminalean ezagutu behar ditugun komandoak hiru dira: cd, dir eta programa bat exekutatu

cmd komandoen terminalak onartzen dituen komandoen artean garrantzitsuenak hauek dira (komando gehiago hemen):

  • dir: directory, uneko karpetaren edukia ikusteko
  • cd: change directory, karpetaz aldatzeko. Adibidez:
    • cd KarpetaBat
      Uneko karpetan barruan KarpetaBat delakorik baldin badago
    • cd ..
      Uneko karpetaren gurasora joateko
  • FitxategiaExekutatu
    Uneko karpetan barruan FitxategiaExekutatu.exe fitxategirik badago exekutatuko da
  • FitxategiaExekutatu Param1 Param2 Param3
    Uneko karpetan barruan FitxategiaExekutatu.exe fitxategirik badago exekutatuko da Param1, Param2 eta Param3 parametroen balioekin

PowerShell komando terminalean ezagutu behar ditugun komandoak hiru dira: cddir eta programa bat exekutatu

PowerShell komandoen terminalak onartzen dituen komandoen artean garrantzitsuenak hauek dira, ikusten denez cmd komandoen terminalaren berdinak dira, baina fitxategiak exekutatu ahal izateko .\ sinboloak jarri behar dira aurretik:

  • dir: directory, uneko karpetaren edukia ikusteko
  • cd: change directory, karpetaz aldatzeko. Adibidez:
    • cd KarpetaBat
      Uneko karpetan barruan KarpetaBat delakorik baldin badago
    • cd ..
      Uneko karpetaren gurasora joateko
  • FitxategiaExekutatu
    Uneko karpetan barruan .\FitxategiaExekutatu.exe fitxategirik badago exekutatuko da
  • FitxategiaExekutatu Param1 Param2 Param3
    Uneko karpetan barruan .\FitxategiaExekutatu.exe fitxategirik badago exekutatuko da Param1, Param2 eta Param3 parametroen balioekin


main() funtzioak onartzen dituen argumentuak ikasteko lehen hurbilpena, ezagutzen dugun programa hau gogoratzea: Lehen koadranteko P puntuaren bi koordenatuak emanik, Kartesiar-Polar bihurketa egiten duen programa. Algoritmoa hauxe da:

  1. XY planoaren lehen koadrantean dagoen P puntu baten koordenatu kartesiarretan (fPx, fPy) teklatutik // irakurri eta...
  2. P puntuari dagozkion koordenatu polarrak lortu (distantzia, angelua)
  3. P puntuaren koordenatu polarraren angelua gradu-minutu-segundotan pantailaratu eta
  4. P puntuaren koordenatu polarraren distantzia pantailaratu

Hauxe da AzkenAriketa_KartesiarPolar-gogoratu programaren kodea, non datuak teklatuz irakurtzen direlako main() funtzioari ez zaion parametrorik pasarazten:

/* AzkenAriketa_KartesiarPolar-gogoratu: main() funtzioak onartzen dituen argumentuak.
                                         Lehen hurbilpena, datuak teklatuz irakurriz. */

// Lehen koadranteko P puntuaren bi koordenatuak emanik, gogoratu KartesiarPolar bihurketa
// egiten zuen programa. Algoritmoa hauxe da:

// XY planoan dagoen P puntu baten koordenatu kartesiarretan (fPx, fPy) teklatutik
// irakurri eta P puntuari dagozkion koordenatu polarrak lortu (distantzia, angelua).
// P puntuaren koordenatu polarraren angelua gradu-minutu-segundotan pantailaratu
// eta P puntuaren koordenatu polarraren distantzia pantailaratu.

#include <stdio.h>
#include <conio.h>  // getche() funtziorako
#include <math.h>   // sqrt() funtziorako   
#define PI 3.141592653

void DatuakHartu(float *fPx, float *fPy);
void RadianGraduMinutuSegundo(float fRadianak, int *iGraduak, int *iMinutuak, float *fSegundoak);

int main()
{
    float fPx, fPy;
    float fDist, fRadianak;
    int iGraduak;          // emaitzaren zati bat
    int iMinutuak;         // emaitzaren zati bat
    float fSegundoak;      // emaitzaren zati bat

    printf("\n==============================================================================\n");

    printf("Zenbaki errealekin lan eginez...\n\n");

    DatuakHartu(&fPx, &fPy);

    fDist = sqrt(pow(fPx, 2) + pow(fPy, 2));
    fRadianak = atan(fPy/fPx);

    printf("\nOP Distantzia = %f unitate", fDist);
    printf("\nAlfa angelua  = %f radian", fRadianak);
    printf("\nKoordenatuak:   (%.3f, %.3f) = [%.3f | %.3f rad]\n", fPx, fPy, fDist, fRadianak);

    RadianGraduMinutuSegundo(fRadianak, &iGraduak, &iMinutuak, &fSegundoak);

    printf("\nOP Distantzia = %f unitate", fDist);
    printf("\nAlfa angelua  = %d\xA7 %d' %.3f\"", iGraduak, iMinutuak, fSegundoak);
    printf("\nKoordenatuak:   (%.3f, %.3f) = [%.3f | %d\xA7 %d' %.3f\"]", fPx, fPy, fDist, iGraduak, iMinutuak, fSegundoak);

    printf("\n==============================================================================\n\n");
    getche();
    return 0;
}


void DatuakHartu(float *fPx, float *fPy)
{
    do
    {

        printf("\"P\" puntuaren x koordenatua eman: ");
        scanf("%f", fPx);
        if (*fPx == 0.0)
            printf("\a\"P\" puntuaren abzisa ezin daiteke 0.0 izan eta 1. koadranteoa izango da\n");
    } while (*fPx <= 0.0);

    do
    {
        printf("\"P\" puntuaren y koordenatua eman: ");
        scanf("%f", fPy);
        if (*fPy == 0.0)
            printf("\a\"P\" puntuaren ordenatua ezin daiteke 0.0 izan eta 1. koadranteoa izango da\n");
    } while (*fPy <= 0.0);
}


void RadianGraduMinutuSegundo(float fRadianak, int *iGraduak, int *iMinutuak, float *fSegundoak)
{
    float fDatuaGradutan;  // datua graduetan
    float fHondarra;       // zenbaki errealaren alde dezimala
    float fMinutuak;       // minutuak adierazteko zenbaki erreala

    fDatuaGradutan = fRadianak*360/(2*PI);
    // printf("\n  fDatuaGradutan = %9.6f", fDatuaGradutan);
    *iGraduak = (int)fDatuaGradutan;
    // printf("\n        iGraduak = %2d", *iGraduak);
    fHondarra = fDatuaGradutan - *iGraduak;
    // printf("\n       fHondarra = %9.6f", fHondarra);

    fMinutuak = 60*fHondarra;
    // printf("\n       fMinutuak = %9.6f", fMinutuak);
    *iMinutuak = (int)fMinutuak;
    // printf("\n       iMinutuak = %2d", *iMinutuak);
    fHondarra = fMinutuak - *iMinutuak;
    // printf("\n       fHondarra = %9.6f", fHondarra);

    *fSegundoak = 60*fHondarra;
    // printf("\n      fSegundoak = %9.6f", *fSegundoak);
    // printf("\n\n %f radian = %02d:%02d:%f gradu-minutu-segundo", fRadianak, *iGraduak, *iMinutuak, *fSegundoak);
}


main() funtzioak onartzen dituen argumentuak ikasteko bigarren hurbilpen honetan datuak ez ditugu teklatuz irakurriko, horren ordez exekuzio-denboran main() funtzioari pasatuko zaizkio lehen koadranteko P puntuaren bi koordenatuak. Hori egiteko bi modu daude.

Komando terminala ireki eta da AzkenAriketa_main-funtzioaren-parametroak programa exekutagarriaren karpetan kokatu. AzkenAriketa_main-funtzioaren-parametroak programaren karpetak egonik komando hau exekutatu cmd terminalean:

  AzkenAriketa_main-funtzioaren-parametroak 7.03 8.45 

Edo beste komando hau PowerSheell terminalean:

.\AzkenAriketa_main-funtzioaren-parametroak 6.91 8.02 

Non lehen parametroa (7.03 edo 6.91) datua den P puntuari dagokion x koordenatu kartesiarra den, eta bigarren parametroa (8.45 edo 8.02) datua den P puntuari dagokion y koordenatu kartesiarra den. Datu horiekin programak, lehen bezala, koordenatu polarraren distantzia eta angelua kalkulatuz pantailaratuko ditu (angelurako gradu-minutu-segundo unitateak erabiliz).

Adibidez, irudi honetan erakusten da AzkenAriketa_main-funtzioaren-parametroak programaren exekuzioa cmd terminalean, programa dagoen C:\Eskolak\2024-25\LaborategikoEskolak\AzkenAriketa_main-funtzioaren-parametroak\bin\Debug karpetatik exekutatuta 1.1 eta 0.5 argumentuekin:

Proiektuaren karpetan kokatu eta AzkenAriketa_main-funtzioaren-parametroa.exe programa exekutatu

Eta irudi honetan exekuzio bera erakusten da cmd terminalean, baina C: unitateko C:\ erroa karpetatik exekutatuta 1.1 eta 0.5 argumentu berdinekin:

C: unitateko erroan kokatu eta AzkenAriketa_main-funtzioaren-parametroa.exe programa exekutatu

Hauxe da AzkenAriketa_main-funtzioaren-parametroak programaren kodea, non programa exekutatzean programari datuak ematen zaizkion main() funtzioaren parametroen bitartez:

/* AzkenAriketa_main-funtzioaren-parametroak: main() funtzioak onartzen dituen argumentuak.
                                              Bigarren hurbilpena, datuak parametro bezala. */

// Lehen koadranteko P puntuaren bi koordenatuak emanik, gogoratu KartesiarPolar bihurketa
// egiten zuen programa. Algoritmoa hauxe da:

// XY planoan dagoen P puntu baten koordenatu kartesiarretan (fPx, fPy) teklatutik
// ez dira irakurtzen eta horren ordez komandoen terminalean emango dira programa
// exekutatzean.
// P puntuari dagozkion koordenatu polarrak kalkulatu (distantzia, angelua).
// P puntuaren koordenatu polarraren angelua gradu-minutu-segundotan pantailaratu
// eta P puntuaren koordenatu polarraren distantzia pantailaratu.

#include <stdio.h>
#include <stdlib.hh>  // atof() funtziorako
#include <math.h>   // sqrt() funtziorako   
#include <conio.h>   // getch() funtzioarako
#define PI 3.141592653

void RadianGraduMinutuSegundo(float fRadianak, int *iGraduak, int *iMinutuak, float *fSegundoak);

int main(int iHiruArgumentu, char *HiruKate[])
{
    int iKont;
    float fPx, fPy;
    float fDist, fRadianak;
    int iGraduak;          // emaitzaren zati bat
    int iMinutuak;         // emaitzaren zati bat
    float fSegundoak;      // emaitzaren zati bat

    printf("\n") ;
    printf("\nHiru kate: Programa exekutagarriaren izen osoa eta bi parametro\n") ;
    for (iKont = 0; iKont < iHiruArgumentu; iKont++)
        printf("\n \t %d. argumentua hau da: |%s|", iKont, HiruKate[iKont]) ;
    printf("\x07\n\nEDOZEIN tekla sakatu aurrera egiteko... ") ;
    getch() ;


    if (iHiruArgumentu != 3)
    {
        printf("\n\nErrorea! main() funtzioak 2 argumentu behar ditu");
        printf("\nP puntu baten Px eta Py koordenatu kartesiarrak.");
        printf("\n\nPrograma bukatzera doa!\n\n");
    }
    else
    {
        printf("\n\n==============================================================================\n");
        printf("Zenbaki errealekin lan eginez...\n");

        fPx = atof(HiruKate[1]);
        if (fPx == 0.0)
            printf("Errorea! (|%s| => %.3f) P puntuaren x abzisa ez da egokia\n", HiruKate[1], fPx);
        fPy = atof(HiruKate[2]);
        if (fPy == 0.0)
            printf("Errorea! (|%s| => %.3f) P puntuaren y ordenatua ez da egokia", HiruKate[2], fPy);

        if (fPx != 0.0 && fPy != 0.0)
        {
            fDist = sqrt(pow(fPx, 2) + pow(fPy, 2));
            fRadianak = atan(fPy/fPx);

            printf("\nOP Distantzia = %f unitate", fDist);
            printf("\nAlfa angelua  = %f radian", fRadianak);
            printf("\nKoordenatuak:   (%.3f, %.3f) = [%.3f | %.3f rad]\n", fPx, fPy, fDist, fRadianak);

            RadianGraduMinutuSegundo(fRadianak, &iGraduak, &iMinutuak, &fSegundoak);

            printf("\nOP Distantzia = %f unitate", fDist);
            printf("\nAlfa angelua  = %d\xA7 %d' %.3f\"", iGraduak, iMinutuak, fSegundoak);
            printf("\nKoordenatuak:   (%.3f, %.3f) = [%.3f | %d\xA7 %d' %.3f\"]", fPx, fPy, fDist, iGraduak, iMinutuak, fSegundoak);
        }
        printf("\n==============================================================================\n\n");
    }

    return 0;
}


void RadianGraduMinutuSegundo(float fRadianak, int *iGraduak, int *iMinutuak, float *fSegundoak)
{
    float fDatuaGradutan;  // datua graduetan
    float fHondarra;       // zenbaki errealaren alde dezimala
    float fMinutuak;       // minutuak adierazteko zenbaki erreala

    fDatuaGradutan = fRadianak*360/(2*PI);
    *iGraduak = (int)fDatuaGradutan;
    fHondarra = fDatuaGradutan - *iGraduak;
    fMinutuak = 60*fHondarra;
    *iMinutuak = (int)fMinutuak;
    fHondarra = fMinutuak - *iMinutuak;

    *fSegundoak = 60*fHondarra;
}



Esan dugu bi modutan pasatu ahal zaizkiola parametroak main() funtzioari exekuzio-denboran, bat komandoen terminalean programa exekutatuz eta bestea Code::Blocks ingurune barnean parametroak adieraziz. Horretarako, menuaren bide hau jarraitu:

Project > Set programs' arguments... > Program arguments:
Project > Set programs' arguments... > Program arguments:

main() funtzioaren goiburua hau izanik int main(int iHiruArgumentu, char *HiruKate[]) ikusten da bigarren argumentua kateen array bat dela eta lehen argumentua zenbaki oso bat dela (arrayaren luzera efektiboa adierazten duen zenbaki osoa). Irudi honek ilustratzen du egoera hori:

Aurrekoarekin jarraituz, AzkenAriketa_main-funtzioaren-parametroak programan ikus daitekeen bezala argumentuak kateak dira. Lehendabiziko katea programaren izena da eta array baten 0 posizioa hartuko du, hurrengo argumentuak (karaktere-kate bat ere) array baten 1 posizioa hartuko du, hurrengo argumentuak (karaktere-kate bat ere) array baten 2 posizioa hartuko du eta horrela argumentu guztiekin.

/* AzkenAriketa_main-funtzioaren-parametroak: main() funtzioaren argumentuak. */

int main(int iHiruArgumentu, char *HiruKate[])

// Programaren exekuzio bakoitzean:

// iHiruArgumentu aldagaiak zenbat argumentu sartu diren gordeko du, gure kasuan 3 zenbakia
//                komeni zaigu: programaren izena, Px koordenatua eta Py koordenatu

// char *HiruKate[] erakusleen arraya da eta kateen erakusleak gordetzen ditu, gure kasuan
//                  3 kateren erakusleak: programaren izena, Px koordenatuaren katea eta 
//                  Py koordenatuaren katea

main() funtzioaren hiru argumentuak kateak dira

Goiko irudian horretan erakusten diren argumentuak hauek dira:

  • 0 argumentua: C:\Eskolak\2024-25\LaborategikoEskolak\AzkenAriketa_main-funtzioaren-parametroak\bin\Debug\main-funtzioaren-parametroak.exe
  • 1 argumentua: "1.1"
  • 2 argumentua: "0.5"

0 argumentua ez da behar izaten programan, baina beste biak bai eta, adibide honetan, 1 eta 2 argumentuak zenbakiak adierazten dituzten kateak dira. Hori dela eta, atof() funtzioari esker lor daiteke katetik zenbakira bihurketa.





  • AzkenAriketa_KartesiarPolar-gogoratu.cbp | main.c  
  • AzkenAriketa_main-funtzioaren-parametroak.cbp | main.c  


 

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

Ariketa 93 | Bi fitxategi bakarrean bildu

ZER DAKIDAN:
Fitxategien algoritmoak ikasi ditut.



ZER IKASIKO DUDAN:
Ikasitako fitxategien algoritmoen aplikazio bat egingo dut: bi fitxategi helburuko fitxategi bakarrean bildu.

Datuak gordetzen dituen bi fitxategi ditugu. Esate baterako, hiru eremuko (izena, adina eta nota) erregistroen fitxategi pare bat daukagu. Hasierako bi fitxategietatik abiatuta fitxategi berri sortuko da aurreko biren informazioarekin.

Hasierako bi fitxategietan lagun batzuen informazioa gordetzen da, lehen fitxategian Jare, Danel, Izaro eta Martin lagunak badaude, bigarren fitxategian lagun berberak egongo dira ordena berean: Jare, Danel, Izaro eta Martin. Adinak ere berdinak izango dira lagun bakoitzeko lehen fitxategian zein bigarrenean (notak ez, notak desberdinak izan daitezke eta adibidez Danelek 7.4 bat izan dezake lehen fitxategian eta 8.6 bigarrenean).

Adibidez, hasierako lehen fitxategiaren edukia hau bada:

C:\Tokia\AgendaZahar1.dat
0   Jare  
   19  
  4.6  
1    Danel   
   18  
  7.4   
2    Izaro   
   18  
  7.1   
3    Martin  
   20   
 6.2 

Hasierako bigarren fitxategiak ondoko hau gorde dezake:

C:\Tokia\AgendaZahar2.dat
0   Jare  
   19  
  3.1  
1    Danel  
   18  
  8.6  
2    Izaro  
   18  
  7.5  
3    Martin  
   20  
  6.0  

Ondorioz, helburuko fitxategiak biltegituko duen informazioa hau izan beharko da:

C:\Tokia\AgendaBerria.dat
0   Jare  
   19  
  4.6  
1    Jare  
   19  
  3.1  
2    Danel  
   18  
  7.4  
3    Danel  
   18  
  8.6  
4   Izaro  
   18  
  7.1  
5    Izaro  
   18  
  7.5  
6    Martin  
   20  
  6.2  
7    Martin  
   20  
  6.0  

Helburuko fitxategia lortzeko algoritmoa erraza da: hasierako lehen fitxategitik irakurri eta helburukoan idatzi, hasierako bigarren fitxategitik irakurri eta helburukoan idatzi. Honela, adibidez:

   ...
    fFitxategi1 = fopen(sFitxIzen1, "rb");    // irakurketarako ireki
    fFitxategi2 = fopen(sFitxIzen2, "rb");    // irakurketarako ireki
    fFitxategia = fopen(sFitxIzena, "wb");    // idazketarako ireki

    for (liKont = 0; liKont < liZenbat; liKont++)
    {
        fread(&stElementua, sizeof(struct tstLaguna), 1, fFitxategi1);
        fwrite(&stElementua, sizeof(struct tstLaguna), 1, fFitxategia);
        fread(&stElementua, sizeof(struct tstLaguna), 1, fFitxategi2);
        fwrite(&stElementua, sizeof(struct tstLaguna), 1, fFitxategia);
    }
   ...

Erakusten den programa honetan lehen fitxategiaren existentzia frogatzen da programa nagusian, horrelako izena duen fitxategirik ez bada sortu egiten da eta, aldiz, eman den izeneko lehen fitxategia aurretik existitzen bada elementu gehiago gehitzeko aukera eskaintzen du programak. Beraz, lehen fitxategiak elementurik izango du bigarren fitxategia sortu baino lehen.

BigarrenAgendakoDatuakLortu(sFitxZahar1, sFitxZahar2, liElemKop) funtzioari esker sortzen da bigarren fitxategia, izenak eta adinak lehen fitxategitik hartuta eta notak auzaz aukeratuta.

Ondoren, datuen bi fitxategiak ditugula, sortuko da helburuko fitxategi osatua informazioa gutiarekin.

Erakusten den programa hau bukatu aurretik, kontaktu jakin baten noten batezbesteko aritmetikoa kalkulatuko da (Danelen kasuan 7.4+8.6=8.0). Horretarako, Danel izenaren bilaketa burutu ondoren kontaktuaren posizioa itzuliko zaio programa nagusiari eta honek fBiNotenMediaKalkulatu() funtzioa aktibatuko du.

/* Ariketa-93_BiFitxategiaBakarreanBildu: bi fitxategi batean batu. */

// Lehen fitxategiaren izena hartuta sortzen da lehendik existitzen ez bada,
// edo aukera dago elementu berriak gehitzeko. Ondoren, bigarren fitxategiko
// datuak lortzen dira (izenak eta adinak berdin mantenduko dira, baina notak
// desberdinak izan daitezke auzaz eskuratzen baitira). Datuen bi fitxategiak
// lortuta helburuko fitxategi osatua eraikitzen da, bukatzeko kontaktu jakin
// baten noten batezbesteko aritmetikoa kalkulatuko da, horretarako izenaren
// bilaketa bat burutu ondoren kontaktuaren indizea itzultzen zaio programa
// nagusiari eta honek fBiNotenMediaKalkulatu() funtzioa aktibatuko du.

#include <stdio.h>
#include <stdlib.h>   // srand() eta rand() funtzioetarako
#include <string.h>   // strcmp() funtziorako
#include <time.h>     // time() funtziorako
#include <ctype.h>    // toupper() funtziorako
#include <conio.h>    // getche() eta getch() funtzioetarako

#define TRUE    1
#define FALSE   0
#define GOIMUGA 9
#define FITX_IZEN_MAX 120  // fitxategiaren izenerako 119 karaktere gehi null mugatzailea
#define DATU_IZEN_MAX  50  // ikaslearen izena gordetzeko 49 karaktere gehi null mugatzailea

struct tstLaguna
{
    char sIzena[DATU_IZEN_MAX];
    int iAdina;
    float fNota;
};

int boFitxategiaBada(const char sFitxIzen[]);
void FitxategiaIkusi(const char sFitxIzen[]);
void LehenAgendaSortuEtaDatuzBete(const char sFitxIzen[]);
void FitxategiariElementuakGehitu(const char sFitxIzen[]);
long int liElementuKopuruaKalkulatu(const char sFitxIzen[]);
void BigarrenAgendakoDatuakLortu(const char sFitxIzen1[],
                                 const char sFitxIzen2[],
                                 long int liElemKop);
void AgendaBerriaLortuDatuakNahastuz(const char sFitxIzen1[],
                                     const char sFitxIzen2[],
                                     const char sFitxIzena[],
                                     long int liElemKop);
long int liKontaktuBatBilatu(const char sFitxIzen[], const char* sGakoa);
float fBiNotenMediaKalkulatu(const char sFitxIzen[], long int liNonDago);


int main()
{
    const char sFitxZahar1[] = "C:\\Tokia\\AgendaZahar1.dat";
    const char sFitxZahar2[] = "C:\\Tokia\\AgendaZahar2.dat";
    const char sFitxBerria[] = "C:\\Tokia\\AgendaBerria.dat";
    char cErantz;
    long int liElemKop;
    float fBatazbestekoa;
    char sGakoa[DATU_IZEN_MAX];
    long int liIndizea;

    srand(time(NULL));

    if (boFitxategiaBada(sFitxZahar1) == TRUE)
    {
        printf("'%s' fitxategia existitzen da, lan egin dezagun.\n\n", sFitxZahar1);
        FitxategiaIkusi(sFitxZahar1);
        do
        {
            printf("Fitxategi horri elementu berriak gehitzea nahi duzu? (B/E): ");
            cErantz = getche();
            cErantz = toupper(cErantz);
            printf("\n");
        } while (cErantz != 'B' && cErantz != 'E');
        if (cErantz == 'B')
        {
            FitxategiariElementuakGehitu(sFitxZahar1);
            FitxategiaIkusi(sFitxZahar1);
        }
    }
    else
    {
        printf("'%s' fitxategia ez da existitzen, sortuko dugu.\n\n", sFitxZahar1);
        LehenAgendaSortuEtaDatuzBete(sFitxZahar1);
        FitxategiaIkusi(sFitxZahar1);
    }

    liElemKop = liElementuKopuruaKalkulatu(sFitxZahar1);
    if (liElemKop > 0)
    {
        BigarrenAgendakoDatuakLortu(sFitxZahar1, sFitxZahar2, liElemKop);
        FitxategiaIkusi(sFitxZahar2);
        AgendaBerriaLortuDatuakNahastuz(sFitxZahar1, sFitxZahar2, sFitxBerria, liElemKop);
        FitxategiaIkusi(sFitxBerria);

        printf("Bilatu nahi duzun kontaktuaren izena: ");
        scanf("%s", sGakoa);
        liIndizea = liKontaktuBatBilatu(sFitxBerria, sGakoa);
        if (liIndizea != -1)
        {
            printf("'%s' kontaktuari %ld indizea dagokio.\n", sGakoa, liIndizea);
            fBatazbestekoa = fBiNotenMediaKalkulatu(sFitxBerria, liIndizea);
            printf("Batazbestekoa: %.2f\n", fBatazbestekoa);
        }
        else
            printf("Ez da '%s' izeneko kontakturik aurkitu.\n", sGakoa);
    }
    else
        printf("Fitxategia hutsik dago.\n");

    printf("\nPrograma bukatzera doa. Edozein tekla sakatu! ");
    getch();  // itxaron edozein tekla sakatu arte

    printf("\n");
    return 0;
}


int boFitxategiaBada(const char sFitxIzen[])
{
    FILE *f = fopen(sFitxIzen, "rb");

    if (!f)
    {
        printf("Fitxategia irekitzean errorea\n\a");
        printf("Ezin izan da '%s' fitxategia ireki\n", sFitxIzen);
        return FALSE;
    }
    else
    {
        fclose(f);
        return TRUE;
    }
}


void FitxategiaIkusi(const char sFitxIzen[])
{
    FILE *fFitxategia;
    struct tstLaguna stElementua;
    long liZenbatElementu;

    fFitxategia = fopen(sFitxIzen, "rb");
    if (!fFitxategia)
    {
        printf("Errorea '%s' fitxategia irakurtzeko irekitzean\n\a", sFitxIzen);
        return;
    }

    fseek(fFitxategia, 0L, SEEK_END);
    liZenbatElementu = ftell(fFitxategia) / sizeof(struct tstLaguna);
    fseek(fFitxategia, 0L, SEEK_SET);

    printf("'%s' fitxategiak %ld elementu ditu, bere edukia:\n", sFitxIzen, liZenbatElementu);
    while (fread(&stElementua, sizeof(struct tstLaguna), 1, fFitxategia))
    {
        printf("%35s %10d %12.2f\n", stElementua.sIzena, stElementua.iAdina, stElementua.fNota);
    }
    printf("\n");
    fclose(fFitxategia);
}


void LehenAgendaSortuEtaDatuzBete(const char sFitxIzen[])
{
    FILE *f;
    struct tstLaguna stElementua;
    int i, iKopurua;

    f = fopen(sFitxIzen, "wb");
    if (!f)
    {
        printf("Fitxategia irekitzean errorea\n\a");
        printf("Ezin izan da '%s' fitxategia sortu\n", sFitxIzen);
        return;
    }

    printf("Zenbat elementu nahi dituzu '%s' fitxategian? ", sFitxIzen);
    scanf("%d", &iKopurua);
    getchar(); // bufferra garbitu

    srand(time(NULL));
    for (i = 0; i < iKopurua; i++)
    {
        printf("%d. lagunaren izena eman: ", i);
        gets(stElementua.sIzena);
        stElementua.iAdina = rand()%10 + 20;
        stElementua.fNota = rand()%10 + (rand()%10)*0.1;
        fwrite(&stElementua, sizeof(struct tstLaguna), 1, f);
    }
    fclose(f);
}


void FitxategiariElementuakGehitu(const char sFitxIzen[])
{
    FILE *f;
    struct tstLaguna stElementua;
    char cErantz;

    f = fopen(sFitxIzen, "ab");
 // f = fopen(sFitxIzen, "r+b");  edo haue ere, baina gero bukaeran kokatuz...
    if (!f)
    {
        printf("Fitxategia irekitzean errorea\n\a");
        printf("Ezin izan da '%s' fitxategia ireki\n", sFitxIzen);
        return;
    }

    srand(time(NULL));
    do
    {
        printf("'%s' fitxategirako lagun baten izena eman: ", sFitxIzen);
        gets(stElementua.sIzena);
        stElementua.iAdina = rand()%10 + 20;
        stElementua.fNota = rand()%10 + (rand()%10)*0.1;
     // fseek(f, 0L, SEEK_END);  baldin eta irekiera "r+b" moduan egin bada
        fwrite(&stElementua, sizeof(struct tstLaguna), 1, f);

        printf("Datu gehiagorik gorde nahi duzu? (B/E): ");
        cErantz = getche();
        printf("\n");
    } while (cErantz == 'B' || cErantz == 'b');

    fclose(f);
}


long int liElementuKopuruaKalkulatu(const char sFitxIzen[])
{
    FILE *fFitxategia;
    long liZenbatElementu;

    fFitxategia = fopen(sFitxIzen, "rb");
    fseek(fFitxategia, 0L, SEEK_END);
    liZenbatElementu = ftell(fFitxategia) / sizeof(struct tstLaguna);

    fclose(fFitxategia);
    return liZenbatElementu;
}


void BigarrenAgendakoDatuakLortu(const char sFitxIzen1[],
                                 const char sFitxIzen2[],
                                 long int liZenbat)
{
    FILE *f1;
    FILE *f2;
    struct tstLaguna stElementua;
    long int liKont;

    f1 = fopen(sFitxIzen1, "rb");
    f2 = fopen(sFitxIzen2, "wb");
    printf(" Aurreko '%s' fitxategiaren orden berean sortuko dira\n", sFitxIzen1);
    printf("bigarren '%s' fitxategiaren datuak (nota berriak dira)\n", sFitxIzen2);
    for (liKont = 0; liKont < liZenbat; liKont++)
    {
        fread(&stElementua, sizeof(struct tstLaguna), 1, f1);
        stElementua.fNota = rand()%10 + (rand()%10)*0.1;  // nota berria
        fwrite(&stElementua, sizeof(struct tstLaguna), 1, f2);
        printf("%ld. indizea duen %-15s lagunaren nota berria eman: %.1f\n", liKont, stElementua.sIzena, stElementua.fNota);
    }
    fclose(f1);
    fclose(f2);
}


void AgendaBerriaLortuDatuakNahastuz(const char sFitxIzen1[],
                                     const char sFitxIzen2[],
                                     const char sFitxIzena[],
                                     long int liZenbat)
{
    FILE *fFitxategi1, *fFitxategi2, *fFitxategia;
    struct tstLaguna stElementua;
    long int liKont;

    fFitxategi1 = fopen(sFitxIzen1, "rb");
    fFitxategi2 = fopen(sFitxIzen2, "rb");
    fFitxategia = fopen(sFitxIzena, "wb");
    if (!fFitxategi1 || !fFitxategi2 || !fFitxategia)
    {
        printf("Errorea fitxategiak irekitzen\n\a");
        return;
    }

    printf("'%s' eta '%s' fitxategiak '%s' fitxategira biltzen...\n", sFitxIzen1, sFitxIzen2, sFitxIzena);

    for (liKont = 0; liKont < liZenbat; liKont++)
    {
        fread(&stElementua, sizeof(struct tstLaguna), 1, fFitxategi1);
        fwrite(&stElementua, sizeof(struct tstLaguna), 1, fFitxategia);
        fread(&stElementua, sizeof(struct tstLaguna), 1, fFitxategi2);
        fwrite(&stElementua, sizeof(struct tstLaguna), 1, fFitxategia);
    }

    fclose(fFitxategi1);
    fclose(fFitxategi2);
    fclose(fFitxategia);
}


// Gogoratu bilaketa egiteko algoritmoa errazago geratzen dela for agindua erabiliz
// Gogoratu ere, indizea itzuli ordez bilatzen den estruktura osoa itzul daitekeela
long int liKontaktuBatBilatu(const char sFitxIzen[], const char sGakoa[])
{
    FILE *f;
    struct tstLaguna stElem;
    int booAurkitua = 0;
    long liIndizea = -1;

    f = fopen(sFitxIzen, "rb");
    if (f == NULL)
    {
        printf("'%s '", sFitxIzen);
        printf("Fitxategia irekitzean errorea\n\a");
        return -1;
    }

    while (fread(&stElem, sizeof(struct tstLaguna), 1, f) == 1 && !booAurkitua)
    {
        if (strcmp(stElem.sIzena, sGakoa) == 0)
        {
            booAurkitua = 1;
            liIndizea = ftell(f) / sizeof(struct tstLaguna) - 1;
        }
    }

    fclose(f);
    return liIndizea;
}


float fBiNotenMediaKalkulatu(const char sFitxIzen[], long int liNonDago)
{
    FILE *fFitxategia;
    struct tstLaguna stElem1, stElem2;
    float fBatazbestekoa = 0.0;

    fFitxategia = fopen(sFitxIzen, "rb");
    if (!fFitxategia)
    {
        printf("Errorea '%s' fitxategia irakurtzeko irekitzean\n\a", sFitxIzen);
        return -1.0;
    }

    fseek(fFitxategia, liNonDago*(long)sizeof(struct tstLaguna), SEEK_SET);
    fread(&stElem1, sizeof(struct tstLaguna), 1, fFitxategia);
    fread(&stElem2, sizeof(struct tstLaguna), 1, fFitxategia);

    fBatazbestekoa = (stElem1.fNota + stElem2.fNota) / 2.0;
    fclose(fFitxategia);
    return fBatazbestekoa;
}






  • Ariketa-93_BiFitxategiaBakarreanBildu.cbp | main.c  


 

Ariketa 92 | Fitxategia bitan banatu

ZER DAKIDAN:
Fitxategien algoritmoak ikasi ditut.



ZER IKASIKO DUDAN:
Ikasitako fitxategien algoritmoen aplikazio bat egingo dut: fitxategi bat helburuko bi fitxategietan banatzea.

Datuak gordetzen dituen fitxategi bat daukagu. Esate baterako, hiru eremuko erregistroen fitxategi bat daukagu (izena, adina eta nota). Jatorrizko fitxategitik abiatuta beste bi fitxategi berri sortuko dira, bietariko batean 25 urte edo hortik beherako ikasleak gordeko dira, beste fitxategi berrian gainerako ikasleak gordeko dira, hots, 26 edo gehiago dituztenak.

Hasierako fitxategitik abiatuta banaketa egiteko garaian hauek dira funtsezko aginduak, jatorrizko fitxategitik irakurri eta helburuko fitxategiren batean idatzi:

   ...
    FILE *f = fopen(sIzena, "rb");                // irakurketarako ireki
    FILE *f25B = fopen(s25etikBeherakoak, "wb");  // idazketarako ireki
    FILE *f25G = fopen(s25etikGorakoak, "wb");    // idazketarako ireki

    while (fread(&stElementua, sizeof(struct tstLaguna), 1, f))
    {
        if (stElementua.iAdina <= 25)
            fwrite(&stElementua, sizeof(struct tstLaguna), 1, f25B);
        else
            fwrite(&stElementua, sizeof(struct tstLaguna), 1, f25G);
    }
   ...

Erakusten den programa honetan fitxategiaren existentzia frogatzen da programa nagusian, horrelako izena duen fitxategirik ez bada sortu egiten da eta, aldiz, eman den izeneko fitxategia lehendik bada elementu gehiago gehitzeko aukera eskaintzen du programak. Beraz, fitxategiak elementurik izango du adibide honen zatirik garrantzitsuenera heltzean.

Uneko fitxategi osoa elementuz-elementu arakatuko dugu eta adinaren arabera idazketa bat egingo da helburuko fitxategi batean ala bestean.

Ikusi adibide honetan, batzuetan getche() funtzioa erabili dela karaktere bat jasotzeko (eta bere ostean printf("\n") bat egiten dela) eta beste batzuetan scanf() funtzioa erabili dela kopuru bat jasotzeko (eta bere ostean getchar() bat egin dela bufferra garbitzeko).

/* Ariketa-92_FitxategiaBitanBanatzen: fitxategi bat bitan banatu. */

// Fitxategiaren izena hartuta sortzen da lehendik existitzen ez bada,
// edo aukera dago elementu berriak gehitzeko. Ondoren, adinen araberako
// fitxategiaren banaketa egiten da bi fitxategi berri sortuz.

#include <stdio.h>
#include <stdlib.h>   // srand() eta rand() funtzioetarako
#include <string.h>   // strcspn() funtziorako
#include <time.h>     // time() funtziorako
#include <ctype.h>    // toupper() funtziorako
#include <conio.h>    // getche() eta getch() funtzioetarako

#define TRUE    1
#define FALSE   0
#define GOIMUGA 9
#define FITX_IZEN_MAX 120  // fitxategiaren izenerako 119 karaktere gehi null mugatzailea
#define DATU_IZEN_MAX  50  // ikaslearen izena gordetzeko 49 karaktere gehi null mugatzailea

struct tstLaguna
{
    char sIzena[DATU_IZEN_MAX];
    int iAdina;
    float fNota;
};

int boFitxategiaBada(const char sFitxIzen[]);
void FitxategiaIkusi(const char sFitxIzen[]);
void FitxategiaSortuEtaBete(const char sFitxIzen[]);
void FitxategiariElementuakGehitu(const char sFitxIzen[]);
void DatuenFitxategiBitanBanatu(const char sIzena[],
                                const char s25etikBeherakoak[],
                                const char s25etikGorakoak[]);

int main()
{
    char sIzenLaburra[FITX_IZEN_MAX];
    char sIzena[FITX_IZEN_MAX];
    char s25etikBeherakoak[FITX_IZEN_MAX];
    char s25etikGorakoak[FITX_IZEN_MAX];
    char cErantz;

    printf("''C:\\Tokia\\'' karpetan lan eginez...\n");
    printf("Lanerako fitxategiaren izen laburra eman (adibidez, 'Lagunak'): ");
    gets(sIzenLaburra);
    strcpy(sIzena, "C:\\Tokia\\");
    strcat(sIzena, sIzenLaburra);
    strcat(sIzena, ".dat");
    printf("Fitxategiaren izen osoa: >>>%s<<<\n\n", sIzena);

    strcpy(s25etikBeherakoak, "C:\\Tokia\\25etikBeherakoak.dat");
    strcpy(s25etikGorakoak, "C:\\Tokia\\25etikGorakoak.dat");

    if (boFitxategiaBada(sIzena) == TRUE)
    {
        printf("'%s' fitxategia existitzen da, lan egin dezagun.\n\n", sIzena);
        FitxategiaIkusi(sIzena);
        do
        {
            printf("Fitxategi horri elementu berriak gehitzea nahi duzu? (B/E): ");
            cErantz = getche();
            cErantz = toupper(cErantz);
            printf("\n");
        } while (cErantz != 'B' && cErantz != 'E');
        if (cErantz == 'B')
        {
            FitxategiariElementuakGehitu(sIzena);
            FitxategiaIkusi(sIzena);
        }
    }
    else
    {
        printf("'%s' fitxategia ez da existitzen, sortuko dugu.\n\n", sIzena);
        FitxategiaSortuEtaBete(sIzena);
        FitxategiaIkusi(sIzena);
    }

    DatuenFitxategiBitanBanatu(sIzena, s25etikBeherakoak, s25etikGorakoak);

    do
    {
        printf("Sortutako bi fitxategi berriak ikusi nahi dituzu? (B/E): ");
        cErantz = getche();
        cErantz = toupper(cErantz);
        printf("\n");
    } while (cErantz != 'B' && cErantz != 'E');
    if (cErantz == 'B')
    {
        FitxategiaIkusi(s25etikBeherakoak);
        FitxategiaIkusi(s25etikGorakoak);
    }

    printf("\nPrograma bukatzera doa. Edozein tekla sakatu! ");
    getch();  // itxaron edozein tekla sakatu arte

    printf("\n");
    return 0;
}


int boFitxategiaBada(const char sFitxIzen[])
{
    FILE *f = fopen(sFitxIzen, "rb");

    if (!f)
    {
        printf("Fitxategia irekitzean errorea\n\a");
        printf("Ezin izan da '%s' fitxategia ireki\n", sFitxIzen);
        return FALSE;
    }
    else
    {
        fclose(f);
        return TRUE;
    }
}


void FitxategiaIkusi(const char sFitxIzen[])
{
    FILE *f = fopen(sFitxIzen, "rb");
    struct tstLaguna stElementua;
    long liZenbatElementu;

    if (!f)
    {
        printf("Fitxategia irekitzean errorea\n\a");
        printf("Ezin izan da '%s' fitxategia ireki\n", sFitxIzen);
        return;
    }

    fseek(f, 0L, SEEK_END);
    liZenbatElementu = ftell(f) / sizeof(struct tstLaguna);
    fseek(f, 0L, SEEK_SET);

    printf("'%s' fitxategiak %ld elementu ditu, bere edukia:\n", sFitxIzen, liZenbatElementu);
    while (fread(&stElementua, sizeof(struct tstLaguna), 1, f))
    {
        printf("%35s %10d %12.2f\n", stElementua.sIzena, stElementua.iAdina, stElementua.fNota);
    }
    printf("\n");
    fclose(f);
}


void FitxategiaSortuEtaBete(const char sFitxIzen[])
{
    FILE *f;
    struct tstLaguna stElementua;
    int i, iKopurua;

    f = fopen(sFitxIzen, "wb");
    if (!f)
    {
        printf("Fitxategia irekitzean errorea\n\a");
        printf("Ezin izan da '%s' fitxategia sortu\n", sFitxIzen);
        return;
    }

    printf("Zenbat elementu nahi dituzu '%s' fitxategian? ", sFitxIzen);
    scanf("%d", &iKopurua);
    getchar(); // bufferra garbitu

    srand(time(NULL));
    for (i = 0; i < iKopurua; i++)
    {
        printf("%d. lagunaren izena eman: ", i);
        gets(stElementua.sIzena);
        stElementua.iAdina = rand()%10 + 20;
        stElementua.fNota = rand()%10 + (rand()%10)*0.1;
        fwrite(&stElementua, sizeof(struct tstLaguna), 1, f);
    }
    fclose(f);
}


void FitxategiariElementuakGehitu(const char sFitxIzen[])
{
    FILE *f;
    struct tstLaguna stElementua;
    char cErantz;

    f = fopen(sFitxIzen, "ab");
    if (!f)
    {
        printf("Fitxategia irekitzean errorea\n\a");
        printf("Ezin izan da '%s' fitxategia ireki\n", sFitxIzen);
        return;
    }

    srand(time(NULL));
    do
    {
        printf("%s fitxategian gordetzeko lagun baten izena eman: ", sFitxIzen);
        gets(stElementua.sIzena);
        stElementua.iAdina = rand()%10 + 20;
        stElementua.fNota = rand()%10 + (rand()%10)*0.1;
        fwrite(&stElementua, sizeof(struct tstLaguna), 1, f);

        printf("Datu gehiagorik gorde nahi duzu? (B/E): ");
        cErantz = getche();
        printf("\n");
    } while (cErantz == 'B' || cErantz == 'b');

    fclose(f);
}


void DatuenFitxategiBitanBanatu(const char sIzena[],
                                const char s25etikBeherakoak[],
                                const char s25etikGorakoak[])
{
    FILE *f = fopen(sIzena, "rb");                // irakurketarako ireki
    FILE *f25B = fopen(s25etikBeherakoak, "wb");  // idazketarako ireki
    FILE *f25G = fopen(s25etikGorakoak, "wb");    // idazketarako ireki
    struct tstLaguna stElementua;

    if (!f || !f25B || !f25G)
    {
        printf("Hiru fitxategiak irekitzean errorea\n\a");
        printf("Ezin izan da fitxategiren bat ireki\n");
        return;
    }
    while (fread(&stElementua, sizeof(struct tstLaguna), 1, f))
    {
        if (stElementua.iAdina <= 25)
            fwrite(&stElementua, sizeof(struct tstLaguna), 1, f25B);
        else
            fwrite(&stElementua, sizeof(struct tstLaguna), 1, f25G);
    }
    fclose(f);
    fclose(f25B);
    fclose(f25G);
}






  • Ariketa-92_FitxategiaBitanBanatzen.cbp | main.c  


 

Ariketa 91 | Fitxategia sailkatu: 16. algoritmoa

[Ez da ikasi behar, nik ez dut galdetuko]

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



ZER IKASIKO DUDAN:
...horregatik, fitxategiko elementu guztiak array laguntzaile batera eramango ditut, arrayan elementuak sailkatuko ditut 11. jarduera | Array bat sailkatu/ordenatu kasuan egin nuen bezala, eta, bukatzeko, arrayaren informazio ordenatua hasierako fitxategian gordeko dut.

Datuak gordetzen dituen fitxategi bat daukagu. Esate baterako, erregistroen fitxategi bat daukagu eta erregistroen eremu bat fNota izendatu da. Programa honen helburua da fitxategia sailkatzea fNota eremuaren arabera, nota txikitenetik nota handienera fitxategia ordenatzea, alegia.

Sailkatze lana oso zaila da fitxategian burutzea, baina array batean egingarria da 11. jarduera | Array bat sailkatu/ordenatu adibidean erakutsi zen bezal. Beraz, jarraian erakusten den programan, lanen sekuentzia hau izango da: fitxategitik arrayra > arraya ordenatu > arraytik fitxategira.  

eta horregatik Datuak gordetzen dituen fitxategi bat daukagu. Esate baterako, erregistroen fitxategi bat daukagu eta erregistroen eremu bat fNota izendatu da. Programa honen helburua da fitxategia sailkatzea fNota eremuaren arabera, nota txikienetik nota handienera fitxategia ordenatzea, alegia.

Erakusten den programa honetan fitxategiaren existentzia ez da frogatzen baina FitxategiaIkusi() funtzioan ezin bada fitxategia ireki programa bukatutzat ematen da. Emandako izena duen fitxategirik bada bere edukia pantailaratzen da eta liZenbatElementu dituen elementuen kopurua kalkulatzen da, liZenbatElementu aldagaiak hartzen duen balioaren arabera erabaki hauek hartuko dira:

  • Baldin eta liZenbatElementu handiagoa bada arrayaren neurria baino, mezu bat erakutsiko da pantailan eta aukera ematen zaio erabiltzaileari beste fitxategi baten izena aukeratu dezan.
  • Fitxategiko elementu guztiak arrayan sar badaitezke urratsak hauek izango dira:
    1. Zehaztutako fitxategiaren edukia array laguntzaile batean gorde
    2. Array laguntzailea fNota arabera sailkatu
    3. Array laguntzailea ordenatuaren edukia jatorrizko fitxategira kopiatu aurreko informazioa galduz
/* Ariketa-91_Fitxategien_16_algoritmoa: sailkatu */

// Erregistroen fitxategi bat ordenatuko da fNota eremuaren
// arabera. Horretarako, fitxategiko edukia array laguntzaile
// batera eramango da sailkatze lana arrayan egiteko da, arraya
// ordenaturik dagoela bere informazioa fitxategian gordeko da.  

#include <stdio.h>
#include <stdlib.h>   // exit() funtziorako
#include <string.h>   // strcspn() funtziorako

#define GOIMUGA 9
#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
#define sBIDEA "C:\\Tokia\\"

// struct edo erregistroa definitzen ikasle baten datuak gordetzeko
struct tstFitxa
{
    char sIzenDeiturak[DATU_IZEN_MAX];
    int iDeialdia;
    float fNota;
};

void FitxategiaIkusi(const char sFitxIzen[]);
void FitxategitikBektoreaBete(const char sFitxIzen[],
                              struct tstFitxa astZerren[],
                              long *liLuzera);
void BektoretikFitxategiaBete(const char sFitxIzen[],
                              struct tstFitxa astZerren[],
                              long liLuzera);
void BektoreaIkusi(const struct tstFitxa astZerren[], long liLuzera);
void NotazOrdenatu(struct tstFitxa astZerren[], long liLuzera);
long liFitxategiarenEsparrua(const char sFitxIzen[]);

int main()
{
    char sFitxIzenLabur[FITX_IZEN_MAX];
    char sFitxIzen[FITX_IZEN_MAX];
    long liZenbatElementu, liLuzera;
    struct tstFitxa astZerren[GOIMUGA];

    do
    {
        printf("Fitxategia existitzen da eta datuak ditu (adibidez C:\\Tokia\\Ikasleak.DAT)\n");
        printf("Fitxategiaren izen laburra eman ('Ikasleak' adibidez): ");
        gets(sFitxIzenLabur);
        strcpy(sFitxIzen, sBIDEA);
        strcat(sFitxIzen, sFitxIzenLabur);
        strcat(sFitxIzen, ".dat");
        printf("Fitxategiaren izen osoa: >>>%s<<<\n\n", sFitxIzen);

        FitxategiaIkusi(sFitxIzen);

        liZenbatElementu = liFitxategiarenEsparrua(sFitxIzen);
        printf("Fitxategiaren elementuen kopurua %ld da eta bektoreak %d elementu onartzen ditu\n", liZenbatElementu, GOIMUGA+1);
        if (liZenbatElementu > GOIMUGA+1)
        {
            printf("'%s' fitxategia handiegia da programa honenzat\n", sFitxIzen);
            printf("Beste fitxategi-izen batekin saiatu!\n\n");
        }
    } while (liZenbatElementu > GOIMUGA+1);

    FitxategitikBektoreaBete(sFitxIzen, astZerren, &liLuzera);

    printf("Bektorea ordenatu baino lehen\n");
    BektoreaIkusi(astZerren, liLuzera);

    NotazOrdenatu(astZerren, liLuzera);

    printf("Bektorea ordenaturik\n");
    BektoreaIkusi(astZerren, liLuzera);

    BektoretikFitxategiaBete(sFitxIzen, astZerren, liLuzera);
    FitxategiaIkusi(sFitxIzen);

    printf("Programa bukatzera doa\n");
    return 0;
}


// fitxategiaren edukia ikusteko funtzioa
void FitxategiaIkusi(const char sFitxIzen[])
{
    FILE *fFitxategia;
    struct tstFitxa stElem;

    fFitxategia = fopen(sFitxIzen, "rb");
    if (!fFitxategia)
    {
        printf("Errorea '%s' fitxategia irekitzean 'FitxategiaIkusi()' funtzioan \a\n", sFitxIzen);
        exit(1);
    }
    printf("Fitxategiaren edukia:\n");
    while (fread(&stElem, sizeof(struct tstFitxa), 1, fFitxategia))
    {
        printf("%-50s %10d %15.2f\n", stElem.sIzenDeiturak,
                                      stElem.iDeialdia,
                                      stElem.fNota);
    }
    printf("\n");

    fclose(fFitxategia);
}


// fitxategitik abiatuta bektorea betetzeko funtzioa
void FitxategitikBektoreaBete(const char sFitxIzen[], struct tstFitxa astZerren[], long *liLuzera)
{
    FILE *fFitxategia;

    fFitxategia = fopen(sFitxIzen, "rb");
    if (!fFitxategia)
    {
        printf("Errorea '%s' fitxategia irekitzean 'FitxategitikBektoreaBete()' funtzioan \a\n", sFitxIzen);
        return;
    }

    *liLuzera = 0;
    while (*liLuzera < GOIMUGA && fread(&astZerren[*liLuzera], sizeof(struct tstFitxa), 1, fFitxategia))
    {
        (*liLuzera)++;
    }
    (*liLuzera)--;

    fclose(fFitxategia);
}


// bektoretik abiatuta fitxategia betetzeko funtzioa
void BektoretikFitxategiaBete(const char sFitxIzen[], struct tstFitxa astZerren[], long liLuzera)
{
    FILE *fFitxategia;

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

    for (long i = 0; i <= liLuzera; i++)
    {
        fwrite(&astZerren[i], sizeof(struct tstFitxa), 1, fFitxategia);
    }

    fclose(fFitxategia);
}


// bektorea ikusteko funtzioa
void BektoreaIkusi(const struct tstFitxa astZerren[], long liLuzera)
{
    printf("Arrayaren edukia:\n");
    for (long i = 0; i <= liLuzera; i++)
    {
        printf("%-50s %10d %15.2f\n", astZerren[i].sIzenDeiturak,
                                      astZerren[i].iDeialdia,
                                      astZerren[i].fNota);
    }
    printf("\n");
}


// bektore baten ordenazioa notaren arabera, aukeraketa metodoaren bidez
void NotazOrdenatu(struct tstFitxa astZerren[], long liLuzera)
{
    for (long k = 0; k < liLuzera; k++)
    {
        long liPosMin = k;
        struct tstFitxa rdMin = astZerren[k];

        for (long j = k + 1; j <= liLuzera; j++)
        {
            if (rdMin.fNota > astZerren[j].fNota)
            {
                rdMin = astZerren[j];
                liPosMin = j;
            }
        }

        // trukatu
        astZerren[liPosMin] = astZerren[k];
        astZerren[k] = rdMin;
    }
}


// fitxategiaren tamaina lortzeko funtzioa
long liFitxategiarenEsparrua(const char sFitxIzen[])
{
    FILE *fFitxategia;
    long liZenbatElem;

    fFitxategia = fopen(sFitxIzen, "rb");
    if (!fFitxategia)
    {
        printf("Errorea '%s' fitxategia irekitzean 'liFitxategiarenEsparrua()' funtzioan \a\n", sFitxIzen);
        return 0;
    }

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

    fclose(fFitxategia);
    return liZenbatElem;
}


Gauza bera egin daiteke erregistroen bi eremuen araberako sailkatze-lana burutuz. Adibidez, demagun erregistroen fitxategia byDeialdia eremuaren arabera sailkatu nahi dela nagusiki, eta byDeialdia eremuaren balioak berdinak direnean sIzenDeiturak eremuaren arabera sailkatuko dela.

Ikus dezagun adibidez ondoko erregistroan oinarritutako fitxategia bat nola sailkatzen den bi eremuen informazioaren arabera. Sailkatze-lana DeialdizEtaNotazOrdenatu() funtzioan egiten da, zeinek array bat ordenatzen duen:

/* Ariketa-91_Fitxategien_16b_algoritmoa: bi eremuen arabera sailkatu */

// Erregistroen fitxategi bat ordenatuko da byDeialdia eremuaren
// eta fNota eremuaren arabera. Horretarako, fitxategiko edukia
// array laguntzaile batera eramango da sailkatze lana arrayan
// eginez (byDeialdia ordenatze-ezaugarri nagusia da eta horrren
// berdintasunik izatean fNota ordenatze-ezaugarri erabiliko da).
// Arraya ordenatuaren informazioa fitxategian gordeko da.

#include <stdio.h>
#include <string.h>  // strcmp() funtziorako
#include <stdlib.h>  // exit() funtziorako

#define GOIMUGA 9
#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
#define sBIDEA "C:\\Tokia\\"

// struct edo erregistroa definitzen ikasle baten datuak gordetzeko
struct tstFitxa
{
    char sIzenDeiturak[DATU_IZEN_MAX];
    int iDeialdia;
    float fNota;
};

void FitxategiaIkusi(const char sFitxIzen[]);
void FitxategitikBektoreaBete(const char sFitxIzen[],
                              struct tstFitxa astZerren[],
                              long *liLuzera);
void BektoretikFitxategiaBete(const char sFitxIzen[],
                              struct tstFitxa astZerren[],
                              long liLuzera);
void BektoreaIkusi(const struct tstFitxa astZerren[], long liLuzera);
void DeialdizEtaNotazOrdenatu(struct tstFitxa astZerren[], long liLuzera);
long liFitxategiarenEsparrua(const char sFitxIzen[]);

int main()
{
    char sFitxIzenLabur[FITX_IZEN_MAX];
    char sFitxIzen[FITX_IZEN_MAX];
    long liZenbatElementu, liLuzera;
    struct tstFitxa astZerren[GOIMUGA];

    do
    {
        printf("Fitxategia existitzen da eta datuak ditu (adibidez C:\\Tokia\\Ikasleak.DAT)\n");
        printf("Fitxategiaren izen laburra eman ('Ikasleak' adibidez): ");
        gets(sFitxIzenLabur);
        strcpy(sFitxIzen, sBIDEA);
        strcat(sFitxIzen, sFitxIzenLabur);
        strcat(sFitxIzen, ".dat");
        printf("Fitxategiaren izen osoa: >>>%s<<<\n\n", sFitxIzen);

        FitxategiaIkusi(sFitxIzen);

        liZenbatElementu = liFitxategiarenEsparrua(sFitxIzen);
        printf("Fitxategiaren elementuen kopurua %ld da eta bektoreak %d elementu onartzen ditu\n", liZenbatElementu, GOIMUGA+1);
        if (liZenbatElementu > GOIMUGA+1)
        {
            printf("'%s' fitxategia handiegia da programa honenzat\n", sFitxIzen);
            printf("Beste fitxategi-izen batekin saiatu!\n\n");
        }
    } while (liZenbatElementu > GOIMUGA+1);

    FitxategitikBektoreaBete(sFitxIzen, astZerren, &liLuzera);

    printf("Bektorea ordenatu baino lehen\n");
    BektoreaIkusi(astZerren, liLuzera);

    DeialdizEtaNotazOrdenatu(astZerren, liLuzera);

    printf("Bektorea ordenaturik\n");
    BektoreaIkusi(astZerren, liLuzera);

    BektoretikFitxategiaBete(sFitxIzen, astZerren, liLuzera);
    FitxategiaIkusi(sFitxIzen);

    printf("Programa bukatzera doa\n");
    return 0;
}


// fitxategiaren edukia ikusteko funtzioa
void FitxategiaIkusi(const char sFitxIzen[])
{
    FILE *fFitxategia;
    struct tstFitxa stElem;

    fFitxategia = fopen(sFitxIzen, "rb");
    if (!fFitxategia)
    {
        printf("Errorea '%s' fitxategia irekitzean 'FitxategiaIkusi()' funtzioan \a\n", sFitxIzen);
        exit(1);
    }
    printf("Fitxategiaren edukia:\n");
    while (fread(&stElem, sizeof(struct tstFitxa), 1, fFitxategia))
    {
        printf("%-50s %10d %15.2f\n", stElem.sIzenDeiturak,
                                      stElem.iDeialdia,
                                      stElem.fNota);
    }
    printf("\n");

    fclose(fFitxategia);
}


// fitxategitik abiatuta bektorea betetzeko funtzioa
void FitxategitikBektoreaBete(const char sFitxIzen[], struct tstFitxa astZerren[], long *liLuzera)
{
    FILE *fFitxategia;

    fFitxategia = fopen(sFitxIzen, "rb");
    if (!fFitxategia)
    {
        printf("Errorea '%s' fitxategia irekitzean 'FitxategitikBektoreaBete()' funtzioan \a\n", sFitxIzen);
        return;
    }

    *liLuzera = 0;
    while (*liLuzera < GOIMUGA && fread(&astZerren[*liLuzera], sizeof(struct tstFitxa), 1, fFitxategia))
    {
        (*liLuzera)++;
    }
    (*liLuzera)--;

    fclose(fFitxategia);
}


// bektoretik abiatuta fitxategia betetzeko funtzioa
void BektoretikFitxategiaBete(const char sFitxIzen[], struct tstFitxa astZerren[], long liLuzera)
{
    FILE *fFitxategia;

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

    for (long i = 0; i <= liLuzera; i++)
    {
        fwrite(&astZerren[i], sizeof(struct tstFitxa), 1, fFitxategia);
    }

    fclose(fFitxategia);
}


// bektorea ikusteko funtzioa
void BektoreaIkusi(const struct tstFitxa astZerren[], long liLuzera)
{
    printf("Arrayaren edukia:\n");
    for (long i = 0; i <= liLuzera; i++)
    {
        printf("%-50s %10d %15.2f\n", astZerren[i].sIzenDeiturak,
                                      astZerren[i].iDeialdia,
                                      astZerren[i].fNota);
    }
    printf("\n");
}


// bektore baten ordenazioa notaren arabera, aukeraketa metodoaren bidez
void DeialdizEtaNotazOrdenatu(struct tstFitxa astZerren[], long liLuzera)
{
    for (long k = 0; k < liLuzera; k++)
    {
        long liPosMin = k;
        struct tstFitxa rdMin = astZerren[k];

        for (long j = k+1; j <= liLuzera; j++)   // ordenatu gabekoen artean minimoa non dagoen zehaztu
        {
            if (
                 (rdMin.iDeialdia > astZerren[j].iDeialdia) ||
                (
                 (rdMin.iDeialdia == astZerren[j].iDeialdia) &&                 // rdMin.iDeialdia berdina denean eta...
                 (strcmp(rdMin.sIzenDeiturak, astZerren[j].sIzenDeiturak) > 0)  // rdMin.sIzenDeiturak handiagoa denean...
                )
               )
            {
                rdMin = astZerren[j];
                liPosMin = j;
            }
        }

        // trukatu
        astZerren[liPosMin] = astZerren[k];
        astZerren[k] = rdMin;
    }
}



// fitxategiaren tamaina lortzeko funtzioa
long liFitxategiarenEsparrua(const char sFitxIzen[])
{
    FILE *fFitxategia;
    long liZenbatElem;

    fFitxategia = fopen(sFitxIzen, "rb");
    if (!fFitxategia)
    {
        printf("Errorea '%s' fitxategia irekitzean 'liFitxategiarenEsparrua()' funtzioan \a\n", sFitxIzen);
        return 0;
    }

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

    fclose(fFitxategia);
    return liZenbatElem;
}






  • Ariketa-91_Fitxategien_16a_algoritmoa.cbp | main.c  
  • Ariketa-91_Fitxategien_16b_algoritmoa.cbp | main.c  


 

Ariketa 90 | Elementu bat kendu: 15. algoritmoa

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



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

Datuak gordetzen dituen fitxategi batekin lan egingo da. Esate baterako, estrukturen fitxategi bat daukagu eta bere posizioa ezaguna den fitxategiko elementu bat kendu nahi da, hots, liZein posizio ezaguneko elementua kendu nahi da fitxategitik.

Jarraian erakusten diren hiru adibideetan liZein posizioaren balioa teklatuz emango du erabiltzaileak. Baina beste egoeraren batean, kendu beharreko elementuaren liZein posizioaren balioa bilaketa baten emaitza izan zitekeen.

Elementuaren ezabaketa burutzeko egitura laguntzaileren bat beharko dugu. Jarraian erakusten den bi programetan egitura laguntzaileak hauek izango dira:

  1. Ariketa-90_Fitxategien_15a_algoritmoa adibidean estrukturen array laguntzaile bat
  2. Ariketa-90_Fitxategien_15b_algoritmoa adibidean estrukturen 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, elementuaren ezabaketa egiteko 9. jarduera | Ezabaketa array batean ikusi zen algoritmoa aplikatuko da.

/* Ariketa-90_Fitxategien_15a_algoritmoa: elementu bat kendu */

// Erregistroen fitxategi batetik elementu jakin bat kentzeko
// fitxategiko edukia array batera igaroko da, kenketa arrayan
// gauzatu eta arrayaren informazio berritua fitxategira ekarri.

#include <stdio.h>
#include <string.h>   // strcpy() eta strcat() funtzioetarako
#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 iFitxategirikBada(const char sFitxIzen[]);
void FitxategiaIkusi(const char sFitxIzen[]);
void BektoreaIkusi(const struct tstFitxa A[], long int liLuzera);
void FitxategitikBektoreaBete(const char sFitxIzen[],
                              struct tstFitxa A[],
                              long int *liLuzera);
void BektoretikFitxategiaBete(const char sFitxIzen[],
                              const struct tstFitxa A[],
                              long int liLuzera);
long int liFitxategiarenElemKopKalkulatu(const char sFitxIzen[]) ;
void Ezabaketa(struct tstFitxa Z[],
               long int *liLuzera,
               long int liZein);


int main()
{
    char sFitxIzen[FITX_IZEN_MAX];
    char sFitxIzenLaburra[FITX_IZEN_MAX];
    long int liZenbatElem, liZein, 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
    strcpy(sFitxIzen, "C:\\Tokia\\");
    strcat(sFitxIzen, sFitxIzenLaburra);
    strcat(sFitxIzen, ".dat");

    if (iFitxategirikBada(sFitxIzen) == 1)
    {
        FitxategiaIkusi(sFitxIzen);
        liZenbatElem = liFitxategiarenElemKopKalkulatu(sFitxIzen);

        if (liZenbatElem <= GOIMUGA)
        {
            FitxategitikBektoreaBete(sFitxIzen, A, &liLuzera);
            BektoreaIkusi(A, liLuzera);
            do
            {
                printf("Ezabatuko den elementuaren posizioa bektorean (%d - %ld): ", BEHEMUGA, liLuzera-1);
                scanf("%ld", &liZein);
            } while (liZein < BEHEMUGA || liZein >= liLuzera);

            Ezabaketa(A, &liLuzera, liZein);
            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;
}


// 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 edukia bistaratzeko
void FitxategiaIkusi(const char sFitxIzen[])
{
    FILE *fFitxategia = fopen(sFitxIzen, "rb");
    struct tstFitxa stElem;
    long int liPosizioa;

    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     %-20s %8d %10.2f\n", liPosizioa, stElem.sIzenDeiturak, stElem.iDeialdia, stElem.fNota);
        liPosizioa++;
    }
    printf("\n");

    fclose(fFitxategia);
}


// fitxategitik abiatuta 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 datuak idazteko
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);
}


// arrayren edukia bistaratzeko
void BektoreaIkusi(const struct tstFitxa A[], long 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 jakin bat arraytik ezabatzeko
void Ezabaketa(struct tstFitxa Z[], long int *liLuzera, long int liZein)
{
    for (int i = liZein; i < *liLuzera - 1; i++)
    {
        Z[i] = Z[i + 1];
    }
    (*liLuzera)--;
}


// 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-90_Fitxategien_15b_algoritmoa: elementu bat kendu */

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

// AzkenaMoztu() funtzioan ftruncate() egiten da eta dagokion f_ZBK
// parametroari balioa emateko fileno() funtzioa erabiltzen 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 iFitxategirikBada(const char sFitxIzen[]);
void FitxategiaIkusi(const char sFitxIzen[]);
long int liFitxategiarenElemKopKalkulatu(const char sFitxIzen[]);
void ElementuaKendu(const char sFitxIzen[],
                    const char sFitxIzenLaburra[],
                    long liNon,
                    long liZenbatElem,
                    struct tstFitxa *stElementuZaharra);
void KendutakoaIkusi(struct tstFitxa stElementuZaharra);


int main()
{
    char sFitxIzen[FITX_IZEN_MAX];
    char sFitxIzenLaburra[FITX_IZEN_MAX];
    struct tstFitxa stElementuZaharra;
    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 (iFitxategirikBada(sFitxIzen) == 1)
    {
        FitxategiaIkusi(sFitxIzen);
        liZenbatElem = liFitxategiarenElemKopKalkulatu(sFitxIzen);
        do
        {
            printf("Kendu behar den elementuaren posizioa fitxategian (0 - %ld): ", liZenbatElem-1);
            scanf("%ld", &liNon);
        } while (liNon < 0 || liNon >= liZenbatElem);

        ElementuaKendu(sFitxIzen, sFitxIzenLaburra, liNon, liZenbatElem, &stElementuZaharra);
        KendutakoaIkusi(stElementuZaharra);
        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;
}


// 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 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);
}


void ElementuaKendu(const char sFitxIzen[],
                    const char sFitxIzenLaburra[],
                    long liNon,
                    long liZenbatElem,
                    struct tstFitxa *stElementuZaharra)
{
    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
    }
    fread(stElementuZaharra, sizeof(struct tstFitxa), 1, f);  // kendu beharrekoa irakurri
    for (liKont = liNon+1; 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: ");
    fgets(stElementua->sIzenDeiturak, 50, stdin);
    stElementua->sIzenDeiturak[strcspn(stElementua->sIzenDeiturak, "\n")] = '\0';

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


void KendutakoaIkusi(struct tstFitxa stElementuZaharra)
{
    printf("========Kendutako elementua:=======================================\n");
    printf("%-15s %8d %10.2f\n", stElementuZaharra.sIzenDeiturak,
                                 stElementuZaharra.iDeialdia,
                                 stElementuZaharra.fNota);
    printf("===================================================================\n");
}






  • Ariketa-90_Fitxategien_15a_algoritmoa.cbp | main.c  
  • Ariketa-90_Fitxategien_15b_algoritmoa.cbp | main.c