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

Ariketa 79 | Bilaketa: 4. algoritmoa

ZER DAKIDAN:
Fitxategiak zer diren badakit, eta fitxategiak irekitzeko w, r eta a markak erabili behar ditudala badakit.



ZER IKASIKO DUDAN:
FILE datu-motarekin jarraituz, elementu baten bilaketa fitxategian nola programatzen den ikasiko dut, baldintza konposatua duen while agindu errepikakor bat erabil daiteke. Baina, errazagoa da fitxategi osoa irakurtzeko while (fread()==1) agindua idaztea eta elementua bilatzean return bitartez prozesu errepikakorra moztea.

Datuak gordetzen dituen fitxategi bat daukagu. Esate baterako, estrukturen fitxategi bat daukagu eta gako bat eman ondoren (adibidez Danel izena) izen horretako elementurik ote dagoen fitxategian jakin nahi dugu, hots, bilaketa bat egin nahi dugu fitxategian eta horretarako iIzenaBilatu() funtzioa idatziko dugu, stIzenaBilatu() funtzioa idatziko dugu edo bestela liIzenaBilatu() funtzioa idatziko dugu.


Algoritmo honek lan gutxiago dauka hurrengo algoritmoak baino. Bilaketa arrakastatsua bada, bilatzen dugun gakoa fitxategian aurkitzen da, orduan iIzenaBilatu() funtzioaren parametro batek estruktura den elementu osoa itzuliko dio programa nagusiari, eta iIzenaBilatu() funtziok TRUE itzuliko du. Aldiz, bilaketak arrakastarik ez badu, bilatzen den gakoa fitxategian aurkitzen ez delako, orduan iIzenaBilatu() funtzioak FALSE itzuliko du.

Erakusten den programa honetan fitxategiaren existentzia frogatzen da programa nagusian, horren arabera:

  • Zehaztutako fitxategiaren edukia pantailaratu
  • Izen bat teklatuz irakurri eta fitxategian bilatzen da, egoera bi hauek aintzat hartzen dira:
    1. Gakoa den izena ez da aurkitzen fitxategian, mezu bat pantailaratzen da
    2. Gakoa den izena fitxategian aurkitzen da, elementu horren datuak pantailaratzen dira
/* Ariketa-79_Fitxategien_4a_algoritmoa: bilaketa bat fitxategian */

// Bilatzen ari den gakoa aurkitzean, estruktura bat den elementu
// osoa itzuliko da (azkenik irakurri den elementua).
// Bestela, estruktura bat itzuliko da baina null karakterea duena.

#include <stdio.h>
#include <stdlib.h>   // exit() funtziorako
#include <string.h>   // strcpy() eta strcmp() funtzioetarako
#include <conio.h>    // getche() eta getch() funtzioetarako

#define sBIDEA "C:\\Tokia\\"
#define FITX_IZEN_MAX 120  // fitxategiaren izenerako 119 karaktere gehi null mugatzailea
#define DATU_IZEN_MAX  72  // ikaslearen izena gordetzeko 71 karaktere gehi null mugatzailea
#define TRUE  1
#define FALSE 0

struct tstFitxa
{
    char sIzenDeiturak[DATU_IZEN_MAX];
    int iDeialdia;
    float fNota;
};


innt iFitxategirikBada(const char *sFitxIzen);
void FitxategiaIkusi(const char *sFitxIzen);
int iIzenaBilatu(const char *sFitxIzen,
                 const char *sGakoa,
                 struct tstFitxa *stElem);


int main()
{
    char sFitxIzenLaburra[FITX_IZEN_MAX];
    char sFitxIzen[FITX_IZEN_MAX];
    char sGakoa[DATU_IZEN_MAX];
    struct tstFitxa stBilatutakoa;

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

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

    if (iFitxategirikBada(sFitxIzen) == 1)
    {
        printf("'%s' fitxategia existitzen da, lan egin dezagun.\n\n", sFitxIzen);
        printf("---------------------------------------------------------------\n");
        FitxategiaIkusi(sFitxIzen);
        printf("---------------------------------------------------------------\n\n");
        printf("Bilatu nahi den ikaslearen izen deiturak eman: ");
        gets(sGakoa);

        if (iIzenaBilatu(sFitxIzen, sGakoa, &stBilatutakoa) == FALSE)
            printf("'%s' izeneko ikaslerik ez dago %s fitxategian\n", sGakoa, sFitxIzen);
        else
        {
            printf("Bilatzen den ikaslearen datu guztiak:\n");
            printf("%50s\n%50u\n%50.2f\n", stBilatutakoa.sIzenDeiturak,
                                           stBilatutakoa.iDeialdia,
                                           stBilatutakoa.fNota);
        }
    }
    else
    {
        printf("'%s' fitxategia ez da existitzen.\n", 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
}


void FitxategiaIkusi(const char *sFitxIzen)
{
    FILE *f;
    struct tstFitxa stFitxa;
    int iPos = 0;

    // Irakurketarako irekitze saiakera ("r" = read)
    // Jakina da fitxategia existitzen dela eta errorerik ez dela izango fopen() funtzioan
    f = fopen(sFitxIzen, "rb");

    printf("'%s' fitxategiaren edukia:\n", sFitxIzen);
    while (fread(&stFitxa, sizeof(struct tstFitxa), 1, f) == 1)
    {
        printf("%d. ", iPos);
        printf("Ikaslea: %-20s  Deialdia: %d  Nota: %.2f\n",
               stFitxa.sIzenDeiturak, stFitxa.iDeialdia, stFitxa.fNota);
        iPos++;
    }

    fclose(f);
}


// Bilatzen den gakoa aurkitzean, emaitza den stEmaitza estrukturak
// irakurritako *stElem parametroak azken elementuaren balioak itzuliko
// ditu eta TRUE marka itzultzen da return bitartez.
// Bestela, aurkitzen ez bada, *stElem parametroak ez du balio ezagunik
// izango eta FALSE marka itzultzen da return bitartez.
int iIzenaBilatu(const char *sFitxIzen, 
                 const char *sGakoa, 
                 struct tstFitxa *stElem)
{
    FILE *f;
    struct tstFitxa stLaguntzailea;

    // Irakurketarako irekitze saiakera ("r" = read)
    // Jakina da fitxategia existitzen dela eta errorerik ez dela izango fopen() funtzioan
    f = fopen(sFitxIzen, "rb");

    while (fread(&stLaguntzailea, sizeof(stLaguntzailea), 1, f) == 1)   // irakurtzeko gai garen bitartean
    {
        if (strcmp(stLaguntzailea.sIzenDeiturak, sGakoa) == 0)
        {
            fclose(f);
            *stElem = stLaguntzailea;
            return TRUE;   // aurkitu da
        }
    }

    fclose(f);
    return FALSE;   // ez da aurkitu
}


/*
// Aurrekoa bezalako baina stLaguntzailea aldagai laguntzailerik gabe
int iIzenaBilatu(const char *sFitxIzen, 
                 const char *sGakoa, 
                 struct tstFitxa *stElem)
{
    FILE *f;

    // Irakurketarako irekitze saiakera ("r" = read)
    // Jakina da fitxategia existitzen dela eta errorerik ez dela izango fopen() funtzioan
    f = fopen(sFitxIzen, "rb");

    while (fread(stElem, sizeof(*stElem), 1, f) == 1)   // irakurtzeko gai garen bitartean
    {
        if (strcmp(stElem->sIzenDeiturak, sGakoa) == 0)
        {
            fclose(f);
            return TRUE;   // aurkitu da
        }
    }

    fclose(f);
    return FALSE;   // ez da aurkitu
}
*/


Algoritmo honek lan gutxiago dauka hurrengo algoritmoak baino. Bilaketa arrakastatsua bada, bilatzen dugun gakoa fitxategian aurkitzen da, orduan stIzenaBilatu() funtzioak estruktura den elementu osoa itzuliko dio programa nagusiari. Aldiz, bilaketak arrakastarik ez badu, bilatzen den gakoa fitxategian aurkitzen ez delako, orduan stIzenaBilatu() funtzioak estruktura bat itzuliko dio ere programa nagusiari, baina izenean null karakterea duena.

Erakusten den programa honetan fitxategiaren existentzia frogatzen da programa nagusian, horren arabera:

  • Zehaztutako fitxategiaren edukia pantailaratu
  • Izen bat teklatuz irakurri eta fitxategian bilatzen da, egoera bi hauek aintzat hartzen dira:
    1. Gakoa den izena ez da aurkitzen fitxategian, mezu bat pantailaratzen da
    2. Gakoa den izena fitxategian aurkitzen da, elementu horren datuak pantailaratzen dira
/* Ariketa-79_Fitxategien_4b_algoritmoa: bilaketa bat fitxategian */

// Bilatzen ari den gakoa aurkitzean, estruktura bat den elementu
// osoa itzuliko da (azkenik irakurri den elementua).
// Bestela, estruktura bat itzuliko da baina null karakterea duena.

#include <stdio.h>
#include <stdlib.h>   // exit() funtziorako
#include <string.h>   // strcpy() eta strcmp() funtzioetarako
#include <conio.h>    // getche() eta getch() funtzioetarako

#define sBIDEA "C:\\Tokia\\"
#define FITX_IZEN_MAX 120  // fitxategiaren izenerako 119 karaktere gehi null mugatzailea
#define DATU_IZEN_MAX  72  // ikaslearen izena gordetzeko 71 karaktere gehi null mugatzailea

struct tstFitxa
{
    char sIzenDeiturak[DATU_IZEN_MAX];
    int iDeialdia;
    float fNota;
};


int iFitxategirikBada(const char *sFitxIzen);
void FitxategiaIkusi(const char *sFitxIzen);
struct tstFitxa stIzenaBilatu(const char *sFitxIzen, const char *sGakoa);


int main()
{
    char sFitxIzenLaburra[FITX_IZEN_MAX];
    char sFitxIzen[FITX_IZEN_MAX];
    char sGakoa[DATU_IZEN_MAX];
    struct tstFitxa stBilatutakoa;

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

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

    if (iFitxategirikBada(sFitxIzen) == 1)
    {
        printf("'%s' fitxategia existitzen da, lan egin dezagun.\n\n", sFitxIzen);
        printf("---------------------------------------------------------------\n");
        FitxategiaIkusi(sFitxIzen);
        printf("---------------------------------------------------------------\n\n");
        printf("Bilatu nahi den ikaslearen izen deiturak eman: ");
        gets(sGakoa);

        stBilatutakoa = stIzenaBilatu(sFitxIzen, sGakoa);

        if (strcmp(stBilatutakoa.sIzenDeiturak, "\0") == 0)
            printf("'%s' izeneko ikaslerik ez dago %s fitxategian\n", sGakoa, sFitxIzen);
        else
        {
            printf("Bilatzen den ikaslearen datu guztiak:\n");
            printf("%50s\n%50u\n%50.2f\n", stBilatutakoa.sIzenDeiturak,
                                           stBilatutakoa.iDeialdia,
                                           stBilatutakoa.fNota);
        }
    }
    else
    {
        printf("'%s' fitxategia ez da existitzen.\n", 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
}


void FitxategiaIkusi(const char *sFitxIzen)
{
    FILE *f;
    struct tstFitxa stFitxa;
    int iPos = 0;

    // Irakurketarako irekitze saiakera ("r" = read)
    // Jakina da fitxategia existitzen dela eta errorerik ez dela izango fopen() funtzioan
    f = fopen(sFitxIzen, "rb");

    printf("'%s' fitxategiaren edukia:\n", sFitxIzen);
    while (fread(&stFitxa, sizeof(struct tstFitxa), 1, f) == 1)
    {
        printf("%d. ", iPos);
        printf("Ikaslea: %-20s  Deialdia: %d  Nota: %.2f\n",
               stFitxa.sIzenDeiturak, stFitxa.iDeialdia, stFitxa.fNota);
        iPos++;
    }

    fclose(f);
}


// Bilatzen den gakoa aurkitzean, emaitza den stEmaitza estrukturak
// irakurritako stElem azken elementuaren balioak hartuko ditu.
// Bestela, aurkitzen ez bada, emaitza den stEmaitza estrukturaren
// sIzenDeiturak eremuan null karakterea gordetzen da.
struct tstFitxa stIzenaBilatu(const char *sFitxIzen, const char *sGakoa)
{
    FILE *f;
    struct tstFitxa stElem;
    struct tstFitxa stEmaitza;

    // Irakurketarako irekitze saiakera ("r" = read)
    // Jakina da fitxategia existitzen dela eta errorerik ez dela izango fopen() funtzioan
    f = fopen(sFitxIzen, "rb");

    while (fread(&stElem, sizeof(struct tstFitxa), 1, f) == 1)   // irakurtzeko gai garen bitartean
    {
        if (strcmp(stElem.sIzenDeiturak, sGakoa) == 0)
        {
            fclose(f);
            stEmaitza = stElem;
            return stEmaitza;
        }
    }

    fclose(f);
    strcpy(stEmaitza.sIzenDeiturak, "\0");
    return stEmaitza;
}

iIzenaBilatu() funtzioaren eta stIzenaBilatu() funtzioaren arteko alderaketa irizpide desberdinen arabera:

Irizpidea

return struct

struct* parametro gisa

Kodearen argitasuna

✅ Bai

❌ Zailagoa

Errendimendua egitura txikietan

✅ Nahikoa

❌ Gehiegizkoa izan daiteke

Errendimendua egitura handietan

❌ Kopiak

✅ Eraginkorra

Kanpoko aldaketak

❌ Ez

✅ Bai

Segurtasun eta kontrola

✅ Arrisku gutxi

❌ Arrisku gehiago

Estruktura txikia denean (oso eremu gutxi dituelako eta gainera eremu txikiak direlako) stIzenaBilatu() funtzioa erabil daiteke, baina gehienetan estrukturak handitxoak direlako iIzenaBilatu() funtzioa hobestuko dugu.


Arrayetan egiten zen bezala: Bilaketa arrakastatsua bada, bilatzen dugun gakoa fitxategian aurkitzen da, orduan liIzenaBilatu() funtzioak elementuaren indizea itzuliko dio programa nagusiari. Aldiz, bilaketak arrakastarik ez badu, bilatzen den gakoa fitxategian aurkitzen ez delako, orduan liIzenaBilatu() funtzioak -1 marka itzuliko dio programa nagusiari.

Bilatzen den elementu osoa itzultzen duen aurreko algoritmoa hobesten da. Izan ere, bilatzen den elementuaren indizea itzultzean, arrayetan ez bezala, fitxategietan datuak ikusteko lan eskerga egin behar da DatuakPantailaratu() funtzioan: (1) fitxategia ireki, (2) jauzia egin, (3) elementua fitxategitik irakurri, (4) pantailan erakutsi eta (5) fitxategia itxi.

Erakusten den programa honetan fitxategiaren existentzia frogatzen da programa nagusian, horren arabera:

  • Zehaztutako fitxategiaren edukia pantailaratu
  • Izen bat teklatuz irakurri eta fitxategian bilatzen da, egoera bi hauek aintzat hartzen dira:
    1. Gakoa den izena ez da aurkitzen fitxategian, mezu bat pantailaratzen da
    2. Gakoa den izena fitxategian aurkitzen da, elementu horren datuak pantailaratzen dira
/* Ariketa-79_Fitxategien_4c_algoritmoa: bilaketa bat fitxategian */

// Bilaketaren funtsa prozesu errepikakor honetan datza:
//     while (fread(&stElem, sizeof(struct tstFitxa), 1, f) == 1)
// Non bilaketa arrakastatzua izatean break bitartez eteten den.

// Bilatzen ari den gakoa aurkitzean, elementuaren indizea fitxategian
// itzuliko da:  liIndizea = ftell(f) / sizeof(struct tstFitxa) - 1;
// Bestela, aurkitzen ez bada, -1 marka itzuliko da.

#include <stdio.h>
#include <stdlib.h>   // exit() funtziorako
#include <string.h>   // strcpy() eta strcmp() funtzioetarako
#include <conio.h>    // getche() eta getch() funtzioetarako

#define sBIDEA "C:\\Tokia\\"
#define FITX_IZEN_MAX 120  // fitxategiaren izenerako 119 karaktere gehi null mugatzailea
#define DATU_IZEN_MAX  72  // ikaslearen izena gordetzeko 71 karaktere gehi null mugatzailea

struct tstFitxa
{
    char sIzenDeiturak[DATU_IZEN_MAX];
    int iDeialdia;
    float fNota;
};


int iFitxategirikBada(const char *sFitxIzen);
void FitxategiaIkusi(const char *sFitxIzen);
long liIzenaBilatu(const char *sFitxIzen, const char *sGakoa);
void DatuakPantailaratu(const char *sFitxIzen, long liIndizea);


int main()
{
    char sFitxIzenLaburra[FITX_IZEN_MAX];
    char sFitxIzen[FITX_IZEN_MAX];
    char sGakoa[DATU_IZEN_MAX];
    long liIndizea;

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

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

    if (iFitxategirikBada(sFitxIzen) == 1)
    {
        printf("'%s' fitxategia existitzen da, lan egin dezagun.\n\n", sFitxIzen);
        printf("---------------------------------------------------------------\n");
        FitxategiaIkusi(sFitxIzen);
        printf("---------------------------------------------------------------\n\n");
        printf("Bilatu nahi den ikaslearen izen deiturak eman: ");
        gets(sGakoa);

        liIndizea = liIzenaBilatu(sFitxIzen, sGakoa);

        if (liIndizea == -1)
            printf("'%s' izeneko ikaslerik ez dago %s fitxategian\n", sGakoa, sFitxIzen);
        else
            DatuakPantailaratu(sFitxIzen, liIndizea);
    }
    else
    {
        printf("'%s' fitxategia ez da existitzen.\n", 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
}


void FitxategiaIkusi(const char *sFitxIzen)
{
    FILE *f;
    struct tstFitxa stFitxa;
    int iPos = 0;

    // Irakurketarako irekitze saiakera ("r" = read)
    // Jakina da fitxategia existitzen dela eta errorerik ez dela izango fopen() funtzioan
    f = fopen(sFitxIzen, "rb");

    printf("'%s' fitxategiaren edukia:\n", sFitxIzen);
    while (fread(&stFitxa, sizeof(struct tstFitxa), 1, f) == 1)
    {
        printf("%d. ", iPos);
        printf("Ikaslea: %-20s  Deialdia: %d  Nota: %.2f\n",
               stFitxa.sIzenDeiturak, stFitxa.iDeialdia, stFitxa.fNota);
        iPos++;
    }

    fclose(f);
}


// Emaitzaren hasieraketa -1 eta irakurtzeko gai garen bitartean...
// Bilatzen den gakoa aurkitzean, azkenik irakurri den elementuaren
// indizea fitxategian itzuliko da:
//       liIndizea = ftell(f) / sizeof(struct tstFitxa) - 1;
// Bestela, aurkitzen ez bada, -1 marka itzuliko da.
long liIzenaBilatu(const char *sFitxIzen, const char *sGakoa)
{
    FILE *f;
    struct tstFitxa stElem;
    long liIndizea = -1;

    // Irakurketarako irekitze saiakera ("r" = read)
    // Jakina da fitxategia existitzen dela eta errorerik ez dela izango fopen() funtzioan
    f = fopen(sFitxIzen, "rb");

    while (fread(&stElem, sizeof(struct tstFitxa), 1, f) == 1)   // irakurtzeko gai garen bitartean
    {
        if (strcmp(stElem.sIzenDeiturak, sGakoa) == 0)
        {
            liIndizea = ftell(f) / sizeof(struct tstFitxa) - 1;
            break;
        }
    }

    fclose(f);
    return liIndizea;
}


// Fitxategia berriro ireki liIndizea*bytak jauzia egin eta bertan irakurketa
// bat burutu estrukturaren balioak pantailaratzeko, ondoren fitxategia itxi
void DatuakPantailaratu(const char *sFitxIzen, long liIndizea)
{
    FILE *f;
    struct tstFitxa stElem;

    // Irakurketarako irekitze saiakera ("r" = read)
    // Jakina da fitxategia existitzen dela eta errorerik ez dela izango fopen() funtzioan
    f = fopen(sFitxIzen, "rb");

    fseek(f, liIndizea*(long)sizeof(struct tstFitxa), SEEK_SET);
    fread(&stElem, sizeof(struct tstFitxa), 1, f);

    printf("%ld indizea duen ikaslea:\n", liIndizea);
    printf("%35s\n%35u\n%35.2f\n",
           stElem.sIzenDeiturak, stElem.iDeialdia, stElem.fNota);

    fclose(f);
}






  • Ariketa-79_Fitxategien_4a_algoritmoa.cbp | main.c       [hau hobesten da]
  • Ariketa-79_Fitxategien_4b_algoritmoa.cbp | main.c
  • Ariketa-79_Fitxategien_4c_algoritmoa.cbp | main.c  


 

iruzkinik ez:

Argitaratu iruzkina